0

A while ago I asked myself, when I write something like this:

   char* first(int howMany){
      return (char*)malloc(howMany);
   } 

   int main(){
      char*t;
      int one=20;
      t=first(20);  
   }

this code crashes at codepad.org but in Mepis Linux 11.04 it just provokes some warnings.

But if I write something like this for C++:

char* first(int howMany){
    return new char [howMany];
   }

int main(){
    char*t;
    int one=20;
    t=first(20);  
}

this code works fine.

My question is:

why doesn't the C-code work and what happens, when I try to

return (char*)malloc(howMany)?

P.S: and what happens if i trying to use in Objective-C this function?

(NSArray*) first(){
    return [NSArray array];
}
Prof. Falken
  • 24,226
  • 19
  • 100
  • 173
gaussblurinc
  • 3,642
  • 9
  • 35
  • 64
  • 2
    The code runs fine (although you aren't freeing all the memory at the end). You just aren't returning an exit status (i.e. you have no `return 0` at the end of `main`). – Oliver Charlesworth Jun 14 '12 at 09:25

2 Answers2

8

I doesn't crash in codepad.org, it runs, but the exit status of the program indicates an error. The exit status is undefined and just what happens to be on the stack by chance, and the exit value (it happens to be 120 on codepad.org) comes from your program not returning anything properly from main(), like it should do.

Traditionally in both C and C++, you had to explicitly return something from main(). In later C and C++ standards, this was changed, so that if you exited main() without a return statement, it would automatically return 0. (0 means success.)

What seems to have happened is that you have a C++ compiler which respects this standard, (standard C++ has had this rule for a longer time than standard C), that if main() is not returning anything, it returns 0 by default.

In contrast, the C compiler on codepad.org seems to follow an older standard, where main() must have an explicit return statement for the program to be valid. So, one could argue that your program fails because codepad.org does not have an up to date C compiler, or one could argue that your program should be more conservative and not assume a modern compiler, and instead return explicitly from main().

That is why the compiler on Mepis Linux warns you. It is probably not configured to follow the latest standard and thus warns you that you should end your main() function with a return statement.

So if you want to write conservative code which works everywhere, your main() function should always end with a return statement. Your very question is proof that it may be dangerous to rely on features of the newer standards if you want your code to work in the "real world".

Changing to Objective C may change something else, but the main problem (pun intended) is still that you are not explicitly returning a value from main() and what standard the C part of Objective C follows in a particular compiler.

That you are not freeing the memory, could well cause a memory leak, but is not an error in the program itself, and is not affecting the issues you observed. (Indeed, on Linux, exiting the program automatically frees all memory, which is perhaps sloppy programming, but not incorrect.)

Community
  • 1
  • 1
Prof. Falken
  • 24,226
  • 19
  • 100
  • 173
  • Sounds like a bug in Codepad: main is supposed to implicitly return 0. – Kaz Dragon Jun 14 '12 at 09:31
  • @KazDragon, depends on which version of the C standard they claim to adhere to. – Prof. Falken Jun 14 '12 at 09:33
  • In C++, if `main` doesn't return then `0` is returned implicitly. – juanchopanza Jun 14 '12 at 09:39
  • @juanchopanza, yes and even in C99. I was writing an update, check above. :-) – Prof. Falken Jun 14 '12 at 09:46
  • 2
    The compiler flags codepad uses for C are `-O -fmessage-length=0 -fno-merge-constants -fstrict-aliasing -fstack-protector-all` and given that it's gcc 4.1.2, it's probably defaulting to C89 with GNU extensions. – JeremyP Jun 14 '12 at 10:17
  • @AmigableClarkKant that's right. C99 says 0 is returned implicitly so I assumed C89, but it compiled a program I put through with an `int` declared in the middle of a block but that compiled too, so I assumed it must be a GNU extension. – JeremyP Jun 14 '12 at 11:01
3

One important difference between C and C++ in this case is that in C++, the main function returns 0 if there is no explicit return. This is the case in your code sample, so it is seen as exiting with success in C++, regardless of any code errors.

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • One important difference between pre C99 and C++ – Prof. Falken Jun 14 '12 at 09:48
  • @AmigableClarkKant thanks for the info, I am not as familiar with C as i am with C++. – juanchopanza Jun 14 '12 at 09:49
  • +1 Your answer is like the technique when a teacher first says to her students, "it's like this", which is sort-of true. Then teacher proceeds with the *real* explanation, which tells the full story but is now easier to understand because of the first, simplified explanation. – Prof. Falken Jun 14 '12 at 10:04