19

Say you have a C code like this:

#include <stdio.h>

int main(){
    printf("Hello, world!\n");
    printf("%d\n", f());    
}

int f(){

}

It compiles fine with gcc, and the output (on my system) is:

Hello, world!

14

But.. but.. how is that possible? I thought that C won't let you compile something like that because f() doesn't have a return statement returning an integer. Why is that allowed? Is it a C feature or compiler omission, and where did 14 come from?

Community
  • 1
  • 1
Nikita
  • 769
  • 2
  • 8
  • 18
  • Why would it fail to let f() return but not main() – Falmarri Nov 23 '10 at 19:42
  • 4
    @Falmarri: because since C99 not returning from main is explicitly allowed as an exception of the rule. Not returning from `main` is equivalent to returning `0` which is equivalent of calling `exit(0)`. – Jens Gustedt Nov 23 '10 at 20:55

7 Answers7

21

The return value in this case, depending on the exact platform, will likely be whatever random value happened to be left in the return register (e.g. EAX on x86) at the assembly level. Not explicitly returning a value is allowed, but gives an undefined value.

In this case, the 14 is the return value from printf.

Adam Vandenberg
  • 19,991
  • 9
  • 54
  • 56
  • 11
    Technically, if a non-`void` function returns without a value *and the function's return value is used*, the behavior is undefined (C99 §6.9.1/12) -- it might return a random value, it could crash, etc. On x86, it will probably just use whatever junk is in the EAX register. But on other architectures, such as IA64, [uninitialized garbage could be deadly](http://blogs.msdn.com/b/oldnewthing/archive/2004/01/19/60162.aspx). – Adam Rosenfield Oct 26 '12 at 19:19
10

compile with -Wall to enable more sanity checking in the compiler.

gcc -Wall /tmp/a.c
/tmp/a.c: In function ‘main’:
/tmp/a.c:5: warning: implicit declaration of function ‘f’
/tmp/a.c:6: warning: control reaches end of non-void function
/tmp/a.c: In function ‘f’:
/tmp/a.c:10: warning: control reaches end of non-void function

Note how it flags up the missing return statements - as "control reaches end of non-void function"?

Always compile using -Wall or similar - you will save yourself heartache later on.


I can recall several occasions when this exact issue has caused hours or days of debugging to fix - it sorta works until it doesn't one day.

Alex Brown
  • 41,819
  • 10
  • 94
  • 108
4

14 is exactly the return value of the first printf, also. Probably, the compiler optimized out the call to f() and then we're left with 14 on EAX.

Try compiling your code with different optimization levels (-O0, -O1, -O2, -O3, -Os) and see if the output changes.

Spidey
  • 2,508
  • 2
  • 28
  • 38
3

18 is the return value of the first print statement. (the number of characters printed)

This value is stored in stack memory.

In second printf function the stack value is 'returned' by function f. But f just left the value that printf created in that slot on the stack.

for example, in this code:

#include <stdio.h>

int main(){
    printf("Hello, world!1234\n");
    printf("%d\n", f());    
}

int f(){

}

Which compiles fine with gcc, and the output (on my system) is:

Hello, world!

18

for details of printf() returning value mail me.

Community
  • 1
  • 1
1

You probably have the warning level of your compiler set very low. So it is allowed, even if the result is undefined.

winwaed
  • 7,645
  • 6
  • 36
  • 81
0

The default return value from a function is int. In other words, unless explicitly specified the default return value by compiler would be integer value from function.

So, the ommiting of return statement is allowed, but undefined value will be returned, if you try to use it.

Vladimir Ivanov
  • 42,730
  • 18
  • 77
  • 103
0

I compile with -Werror=return-type to prevent this. GCC will give an error if you don't return from a function (unless it's void return).

Matt Joiner
  • 112,946
  • 110
  • 377
  • 526