116

I was just reading

ISO/IEC 9899:201x Committee Draft — April 12, 2011

in which i found under 5.1.2.2.3 Program termination

..reaching the } that terminates the main function returns a value of 0. 

it means if you don't specify any return statement in main(), and if the program runs successfully, then at the closing brace } of main will return 0.

But in the following code i don't specify any return statement, yet it does not return 0

#include<stdio.h>
int sum(int a,int b)
{
return (a + b);
}

int main()
{
    int a=10;
    int b=5;
    int ans;    
    ans=sum(a,b);
    printf("sum is %d",ans);
}

compile

gcc test.c  
./a.out
sum is 15
echo $?
9          // here it should be 0 but it shows 9 why?
Jeegar Patel
  • 26,264
  • 51
  • 149
  • 222
  • Did you compile with a C99 (or greater) compiler? – pmg Dec 30 '11 at 08:42
  • 69
    +1 for having the patience to read specs..... – Asher Dec 30 '11 at 08:42
  • i have compile with gcc with no extra option/flag? – Jeegar Patel Dec 30 '11 at 08:43
  • 16
    `gcc` by itself (for version 4.6.2) compiles a language very similar but not quite like C. It compiles GnuC89 -- a language "loosely" based on C89. – pmg Dec 30 '11 at 08:45
  • 2
    The parentheses on the `return` statement in `sum()` are unnecessary. `int main()` should be `int main(void)`. – Keith Thompson Dec 30 '11 at 08:47
  • 24
    Confusion != typo. On my keyboard '0' and 'o' are close enough for it to easily be the latter. ;-) – The111 Dec 30 '11 at 09:09
  • 2
    IMHO is a quite stupid specification, since it forces the compiler to manage the "main" function in a special way by adding an implicit "return 0". So a function named "main" behaves in a slightly different way. What about the compile-time checks ("no return value" an similar)? – Giuseppe Guerrini Dec 30 '11 at 12:29

3 Answers3

142

That rule was added in the 1999 version of the C standard. In C90, the status returned is undefined.

You can enable it by passing -std=c99 to gcc.

As a side note, interestingly 9 is returned because it's the return of printf which just wrote 9 characters.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
cnicutar
  • 178,505
  • 25
  • 365
  • 392
  • 42
    Or you can just add `return 0;` before the closing `}`. It's harmless and makes your program portable to older compilers. – Keith Thompson Dec 30 '11 at 08:46
  • does } of main will return 0 is added in c99 or its part of older version of c? – Jeegar Patel Dec 30 '11 at 08:47
  • or even `-std=c1x` which seems to be supported starting with gcc 4.6 :) – Jens Gustedt Dec 30 '11 at 08:47
  • @cnicutar hey "interestingly" main() in such condition always return what its last called function return..!! is it co-incidence or any reasion behind that? – Jeegar Patel Dec 30 '11 at 08:56
  • @Mr.32 I wouldn't depend on it, it's not like perl :-) – cnicutar Dec 30 '11 at 08:57
  • @cnicutar i will also not depend and never forget to return statement but " always just curious about how things works" – Jeegar Patel Dec 30 '11 at 08:58
  • 2
    @Mr.32 : good observation, printf() returns the length of the string so it is 9 which is the "return" ofthe main (without using -std=c99). – Hicham Dec 30 '11 at 09:16
  • @cnicutar : but, the return value of printf() is lost, i wonder where it is stored. – Hicham Dec 30 '11 at 09:21
  • i thought that all locals in stack in main(or other function) were removed after the end of main (or other function)... so i have to give a look for exact content of stack in all cases. – Hicham Dec 30 '11 at 09:34
  • 1
    @cnicutar: Functions don’t typically return small values on the stack—because it would involve a pop, a push, and a jump rather than just a move and a return—so it’s almost certainly a register, `eax` specifically on x86. – Jon Purdy Dec 30 '11 at 09:37
  • 8
    Yes, the x86 API usually return integer like value via the `eax` register. See http://en.wikipedia.org/wiki/X86_calling_conventions#cdecl for more information. – Sylvain Defresne Dec 30 '11 at 10:04
  • 1
    Apparently this bug predates C and Unix... http://lists.ding.net/geeks/96/sep/msg00115.html – JoelFan Dec 30 '11 at 16:10
  • 2
    Several times I've seen code like "int foo(void) { bar(); }", where "return bar()" was intended. This code works just fine on most processors, despite the obvious bug. – ugoren Jan 03 '12 at 19:51
  • 1
    @SylvainDefresne, you mean the ABI. :-) – Prof. Falken May 25 '12 at 07:48
15

It returns return value of printf which is number of characters really printed out.

Summer_More_More_Tea
  • 12,740
  • 12
  • 51
  • 83
  • the question does not talk about what is printed in the consolewhen executing the program, it talks about the return value of the program : (you can get it in linux with the schell command : echo $? and in windows with : echo %errorlevel%) – Hicham Dec 30 '11 at 09:10
  • 1
    @eharvest Though I don't know how to check `%errorlevel%` in Windows, any difference between exit code and return value of `main` in linux? – Summer_More_More_Tea Dec 30 '11 at 09:33
  • 1
    @eharvest: The answer doesn't not talk about what is printed in the console also. It talks about the _return value_ of `printf` which in this case is 9 which then gets "promoted" as the exit code from `main` somehow when using certain gcc versions. – A.H. Dec 30 '11 at 09:47
  • sorry. my mistake. you are right. i read this answer too fast :/ – Hicham Dec 30 '11 at 09:53
  • "how to check %errorlevel%" : in a console execute the program in a console then write: echo %errorlevel% to get the return value of the program. – Hicham Dec 30 '11 at 09:56
  • 1
    Note that this is *not* guaranteed. In C89/C90, the status returned in this case is *undefined*; it could be anything. It happens to return 9 because the compiler made no effort to return anything else. Other compilers will likely behave differently. – Keith Thompson Dec 30 '11 at 20:31
6

The return value from a function is normally stored in the eax register of the cpu, so the statement "return 4;" would usually compile to

mov eax, 4;
ret;

and return x (depending on your compiler) would be something like:

mov eax, [ebp + 4];
ret;

if you don't specify a return value then the compiler will still spit out the "ret" but doesn't change the value of eax. So the caller will think that what ever was left in the eax register previously is the return value. For this example it would usually be the return value printf, but different compilers will generate different machine code and use some registers differently.

This is a simplified explanation, different calling conventions and target platforms will play a vital role but it should be enough information to explain what is happening 'behind the scenes' in your example.

If you've got a basic understanding of assembler it's worth comparing the disassembly of different compilers. You may find that some compilers are clearing the eax register as a safeguard.

noggin182
  • 627
  • 4
  • 14
  • 11
    The compiler _might_ do that. It's undefined. It may instead choose to shoot you in the head with a printer cartridge. – Lightness Races in Orbit Jan 03 '12 at 18:01
  • @LightnessRacesinOrbit undefined is not the same as unpredictable, ie from "if the compiler does X, it will be standard conforming" it does not logically follow "the compiler might do X" – Owen Nov 23 '13 at 02:09
  • @Owen: Quote the standard passage defining this. – Lightness Races in Orbit Nov 23 '13 at 04:12
  • 2
    @LightnessRacesinOrbit I'm sorry I don't quite follow. I guess what I really want to say is that I think that under-the-hood insights such as noggin182 provided in this answer are incredibly useful for debugging. When your program is producing unexpected results, a lot of times you don't know where they are coming from or even where in the code to look, and having an understanding of the implementation details can point you in the right direction. – Owen Nov 23 '13 at 05:41
  • @Owen I never claimed otherwise – Lightness Races in Orbit Nov 23 '13 at 11:47