Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

zt0ne

macrumors newbie
Original poster
Feb 4, 2014
6
0
Hey,
I just converted from using Windows & Linux to using Mac, so I am pretty new to the Mac environment. However, that doesn't appear to be the problem here.

I am currently working on a C application for university. The application itself includes some basic C, a bunch of elements stored in a struct and so on. Nothing that fancy. I've been working on my Linux Laptop to compile and debug this application up until today, where I finally got my MacBook Pro.

I've installed GCC on the Mac from the Apple Developers page (Command Line Tools OSX Mavericks) - the application seems to compile just fine (I am using gcc -Wall -o name name.c)

On my Linux computer, the program runs fine after compiling, no warnings, no issues whatsoever. However, on this computer, when I run it, it just does nothing ... I am running the application with ./name while being in the directory of the file. Normally the program should give a prompt where the user can enter some basic commands. This output doesn't show up at all. In fact, when I edit my main() function and insert a printf right at the beginning, I am not even getting to see that!? I am pretty confused, I've searched through google for the last 2 hours and found basically nothing about the problem.

When I start the program by typing ./name it just does nothing and lets me input stuff until I press Ctrl-C ...

Does anyone know what could cause this problem? Other basic applications with a few printf() and some calculations work just fine, just this particular one doesn't seem to work while giving no error at all.(I can't put the code of the program online because it is for an university assignment)

Thanks in advance
 
Last edited:
Does anyone know what could cause this problem?

Not really. If you can not post the code then it's pretty much impossible to answer what could cause this. Chances are you are relying on undefined behavior somewhere which just happens to work on one platform but not the other, but that's a guess.

Perhaps you could ask someone to help you at your university?
 
Does anyone know what could cause this problem? Other basic applications with a few printf() and some calculations work just fine, just this particular one doesn't seem to work while giving no error at all.(I can't put the code of the program online because it is for an university assignment)

Thanks in advance

Start deleting code from your program a few lines at a time and post the smallest program you can that still has this problem.

Likely in the process you will find the problem. It may not even be a problem with mac OS X but just a bug in your code, writing over some array bound or whatever that just happens to have different effects depending on what you have over written.
 
Thanks for replying so fast, I've been checking a few things, but I can't seem to find the error. The whole deleting line by line thing is not that easy though, the program is supposed to represent a "friend" networking system, consisting of over 800 lines of code. The basic process is reading out of a .csv file .. It seems to me that there is a problem reading out the data from the file.

I am using this portion right here to initialize the file, I could imagine the problem there.

Code:
FILE *input_file;
  input_file = fopen("/Users/stone/Downloads/filename.csv", "r");
  if(input_file == NULL)
  {
    OUTPUT_FILE_NOT_FOUND;
    return RETURN_FILE_NOT_FOUND;
  }
  fseek(input_file, 0, SEEK_END);
  if(ftell(input_file) < 4)
  {
    OUTPUT_FILE_CORRUPT;
    return RETURN_FILE_CORRUPT;
  }
  rewind(input_file);

The CAPS letters represent define values like this:

Code:
#define RETURN_FILE_CORRUPT (-5)
#define OUTPUT_FILE_CORRUPT (printf("error: file corrupt\n"))
 
I am using this portion right here to initialize the file, I could imagine the problem there.

But you are just opening the file, checking that it exist and is not below your minimum size. You said something about a prompt not showing up?
 
The program goes through the file to generate the linked list with all the values, afterwards it goes into an endless loop to wait for user input. Basically it shows a prompt and waits for input. Basically there are just 3 functions in my main() - one that reads the csv and generates the list, another one that generates the representations of the relationships that are specified in the file, and a last one that is called after those 2 that basically just goes into an endless loop and scans for user input.

It goes through the input char by char and should read until \n or \0, which works fine on the gcc on my Linux laptop - that's what is basically confusing me so hard. Are the "escape" values, like \n or \0 any different on a Mac? As I mentioned, I am new to the Mac and just trying to figure things out.

Now instead of executing the reading functions and then giving me the prompt, it just does nothing and lets me input stuff.

I am typing ./name into the terminal and press enter - it is going into the next line and does - nothing. I can input stuff and press enter or anything I want, it continues to do nothing until I go and press Ctrl-C.

Interestingly enough, if I add a printf() directly at the beginning of the main function, it does NOT get executed. However, if i delete the readFile function from the main(), the printf is getting executed fine and I am getting my prompt as well as intended.
 
You said that you don't even get a printf at the top of main() showing up. What happens if you delete everything from main() except for the printf and return 0; ?

Edit: You replied while I was typing that; interesting about your readFile function "killing" it but as a Windows developer I can't suggest much else!
 
The program goes through the file to generate the linked list with all the values,

The point is you are not showing code that is related to the problem you describe.

Does a simple hello world work?
 
Yes, a simple file works just fine.

Our previous work for university contains about 1400 lines of code + a similar approach with a linked list and reading from mp3 files, that still works like a charm, without any difficulties at all. It is just this one application that I can't seem to run ...
 
Yes, a simple file works just fine.

Our previous work for university contains about 1400 lines of code + a similar approach with a linked list and reading from mp3 files, that still works like a charm, without any difficulties at all. It is just this one application that I can't seem to run ...

So you have a bug in your code. But without showing the code it's hard to tell what's going on. Why not just show it to someone at the university if you can not post code.
 
Well it seems like there must be a bug, but I still don't get how I got to run the application on two different Linux systems, both compiled with GCC, running fine, without warnings, without any problem.

Since we have a tight time limit on the assignment, I won't be able to ask for help at the university atm. I will just stick to a Linux compiler for now, but thank you all for your help!

I really thought I was just making a very stupid mistake as a OSX newbie, but apparently there seems to be more behind it.

Thanks for your assistance!
 
The CAPS letters represent define values like this:

Code:
#define RETURN_FILE_CORRUPT (-5)
#define OUTPUT_FILE_CORRUPT (printf("error: file corrupt\n"))

This is completely unrelated to your bug, but DO NOT USE DEFINE FOR THIS! Do you understand how #define works? If the answer is "Yes", then you'll understand the problem and readily accept what I'm going to suggest as an alternative. If the answer is "No", then you should smack someone across the face for introducing you to #define without explaining it in adequate depth, and then use what I'm about to suggest (and I'm not going to explain the problems here with #define because it's incredibly unlikely that you'll ever come across a situation where you actually need it - you should just never use it again.)

Code:
const int RETURN_FILE_CORRUPT = -5;

Here you see the const keyword, added in C89 - 25 years ago. People use it (as they should) in C++, but for some reason act like it doesn't exist when they're writing C code - it does, and you should use it, not #define, when you're trying to make a constant value.

As for your other #define, you should use this:

Code:
void OUTPUT_FILE_CORRUPT() {
    printf("error: file corrupt\n");
}

Here you see a function, which has existed since the very earliest version of C, even before it was standardized by ANSI. I've seen arguments for using #define instead of a proper function in cases where the function needs to be able to take multiple types of parameters (I'm still debating whether or not that's actually a valid use case for #define) but this function takes no arguments, so there's definitely no reason to be using a #define.

----------

Well it seems like there must be a bug, but I still don't get how I got to run the application on two different Linux systems, both compiled with GCC, running fine, without warnings, without any problem.

Since we have a tight time limit on the assignment, I won't be able to ask for help at the university atm. I will just stick to a Linux compiler for now, but thank you all for your help!

I really thought I was just making a very stupid mistake as a OSX newbie, but apparently there seems to be more behind it.

Thanks for your assistance!

Which version of GCC are you running on each of the Linux systems? Which version are you running on OSX (is it even GCC? I was under the impression that gcc was aliased to a different compiler... clang?)
 
Problem solved!

Since we were reading with fgetc() we were using EOF to break the operation. I figured that I get -1 as a EOF value - so I modified our if conditions a bit, and it works fine now!

To us #define was introduced in a very brief introduction, we didn't get any further information about it. We thought it would be okay to use define in that case. I'll read up about that, thanks for pointing that out.

Thanks for your help!
 
Just some general words of advice...

  • Use warnings - i.e. always compile with -Wall.
  • When available, use clang over gcc. The diagnostics are (IMO) better.
  • Learn to use gdb (or Xcode's debugger). It will save you hours of guessing what is going wrong.
  • Try the clang static analyzer.
 
To us #define was introduced in a very brief introduction, we didn't get any further information about it. We thought it would be okay to use define in that case.

Lines that start with # is code that is run before your code compiles. In the case of #define, it'll actually modify the code you're compiling. If you happen to have the same sequence of characters occur somewhere in your code, it'll replace that sequence of characters and you'll end up with the most impossible to debug issues I've ever seen.

IE, if you have
Code:
#define RETURN_CODE 0
and then later have
Code:
int RETURN_CODE = 0;
you'll end up with the compiler trying to compile
Code:
int 0 = 0;

Some compilers will actually tell you the real problem here, that you used a defined value, likely by mistake. Most compilers aren't that smart and will tell you they were expecting a valid identifier but found 0 instead (and since it'll point out that line, you'll think the zero it found was the one on the right, since you have a valid identifier on the left). I wasted two hours with this a few days ago because a library I was using had used a #define internally with the same name I was using in my own code. It's not a rare problem, either - I probably hit it once for every 500 hours or so I work in C.

If everyone just uses const int instead, you'll end up with the error that you're trying to redefine a const value, which is a lot more helpful.

I need to write up a blog post explaining the follies of #define...
 
I probably hit it once for every 500 hours or so I work in C.

If everyone just uses const int instead, you'll end up with the error that you're trying to redefine a const value, which is a lot more helpful.

I actually never had that happen, perhaps because I don't use upper case identifiers for variables. Also, at least the #define will give you a compile error in this case. A const int defined value would compile just fine but potentially using a wrong value than you expect, ie where someone mistakenly redefining a global constant, or more accurately using two identifiers with the same name.
 
#define

#define is a compiler directive. If you have for example:
Code:
#define k_NAME -1
in your file , the pre-compiler will replace every instance of k_NAME with -1 before compiling. You don't include your definition of
Code:
OUTPUT_FILE_NOT_FOUND;
but if it's defined like your
Code:
#define RETURN_FILE_CORRUPT (-5)
this will result in a line of code that is (-5); before compiling which would appear to do nothing.
Code:
return RETURN_FILE_NOT_FOUND;
in your
Code:
int main(int argc, const char * argv[])
function would end your program by returning some value to your calling environment. If this happened, your program would end, so your program is probably running correctly. You should include some lines of code that report errors to the the log window, like
Code:
printf("failed to open input file\n");
If you
Code:
#include <errno.h>
your file will have a variable errno which will contain a value that describes the error that you can look up in the errno.h header file, so you could include for example:
Code:
printf("failed to open input file - error number %d\n", errno);
Be sure to include the "\n" because this will cause it to be logged immediately. As mentioned above, debuggers are invaluable for debugging. You could step through your code with break points set and see what's happening. When I'm developing C code with no GUI I still do it as an XCode .c project because of the very powerful debugging, error checking, code analysis, etc.
 
Error Checking

Also I should mention that in real-world program development a lot of code is not written like this
Code:
foo();
it's looks like this:
Code:
if(foo() == WTF){
   logError();
   alertUser(); //With a real comprehensible error message - not error !@#$%
   takeEvasiveAction();
   return(FUBAR);
}
 
To give an example to the #define post above, if I have the files define.c and define.h

Code:
const int DEFINE = 1;

Code:
#include <stdio.h
#include "define.h"

int main()
{
    const int DEFINE = 0;
    printf("%d\n", DEFINE);

    return 0;
}

This will compile without any warnings and print 0. If this was #defined then it would produce a compile error and at least with clang, point out the #define with a file and line nr reference.

If DEFINE was #defined and later redifined in .c then I would get a warning about a macro being redefined, even without any extra compile flags in both gcc and clang.

Finally, defining a const declared variable in a header is not possible in C++, you then need to declare it "extern const int name;" then define it in a separate cpp file with the identifier i.e "name = 123;".
 
Problem solved!

Since we were reading with fgetc() we were using EOF to break the operation. I figured that I get -1 as a EOF value - so I modified our if conditions a bit, and it works fine now!

You'll find that EOF is defined on both Linux and OS X in /usr/include/stdio.h.

On both platforms EOF is defined as -1.

There are many differences that you will find moving even basic code from one platform to another. Debugging problems on a new platform is essentially the same process as debugging code that you are writing. Specifically, use a debugger or print statements to isolate the areas of code that are not behaving as expected then identify the cause of the problem. With cross-platform issues the answer is often found by reading the man pages for the relevant library calls.
 
That should NOT be true with ANSI C. It is standardized and should run exactly the same on all platforms.

There are external factors, such as file-system structure, that can't be encapsulated in any ANSI standard.

The main problem with any critique at this point is we don't have a complete body of code to examine, analyze, debug, or comment on. Everyone is just speculating as to what the OP's malfunctioning code actually is or was. The malfunction wasn't in the posted code fragment, because the OP later said the problem was solved with EOF, and there's no EOF in the posted fragment.

The only posted code is a fragment that contains a pathname specific to OS X. That is, it won't work as given on Linux or Windows unless one first creates that exact directory structure (the presence or absence of which is beyond ANSI standards). Other than the pathname, that posted code fragment is portable; even the #defines.
 
That should NOT be true with ANSI C. It is standardized and should run exactly the same on all platforms.

The vast majority of programs that go beyond "Hello World" will use libraries. Even fairly innocuous libraries can exhibit differences in semantics that are platform-specific.

There are plenty of areas of ANSI C where the various specifications define behavior as either "undefined", or "implementation dependent".
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.