-2

Can someone please explain the behavior of the following code. How come the function message() with return type int is returning the no of characters printed by printf() function without any return statement ?

#include <stdio.h>

int message();

int main() {
  int c;
  printf("C before:%d\n",c);
  c=message();
  printf("C after:%d\n",c);
  return 0;  
}

int message(){
  printf("From the message");
}
Kunal Kumar
  • 67
  • 3
  • 6
  • 3
    The (anti-)miracle of _undefined behaviour_. – underscore_d Jul 17 '15 at 14:30
  • printf returns the number of characters. Its return value is evidently put somewhere on the stack. The implementation of assigning a function call to a variable in some implementations is apparently some sort of pointer to where the function would return a value if it returned a value. Since there isn't a return value you are doing something like following a dangling pointer. In this implementation it happens to point to a value which is related to what the function did, but nothing in the C standard guarantees that behavior. – John Coleman Jul 17 '15 at 14:40

3 Answers3

2

This is caused by undefined behaviour.
Here's a similar question, and I couldn't put it any better than the second answer does:

That's simply undefined behaviour; if you don't populate the return area [...], it'll have the value last set up through some side-effect in your function.

...which is the value returned by printf.

Community
  • 1
  • 1
Siguza
  • 21,155
  • 6
  • 52
  • 89
1

It's undefined behavior ...

As there is no return set in message(), it will set C to garbage.

Neil
  • 1,036
  • 9
  • 18
  • There is no single value of `c` mandated by the standard, but in this case, it's not "garbage"; it's the cached return value of `printf`. Of course, due to being UB, it might be something totally different on another compiler/system, so it _might as well be_ garbage. – underscore_d Jul 17 '15 at 14:32
  • 1
    I would class that as garbage. - Ahh - you edited your comment! :-) – Neil Jul 17 '15 at 14:34
  • All I meant was that in this case, on that one system, it's not a random value. But yes, for sure, UB is garbage in the sense that no one should ever deliberately program to it. - Ah, you saw my edit. :D – underscore_d Jul 17 '15 at 14:38
  • In some ways it is worse than garbage. It is a predictable value (in gcc at least) but one which isn't guaranteed. If you are targeting a specific compiler you can write functioning code which uses these pseudo-returns. But then another compiler (or even perhaps the same compiler with different settings) could break the code. It is like edible garbage that can become toxic without warning. – John Coleman Jul 17 '15 at 14:49
1

It is undefined behavior.

For example, if you compile it with clang and run it, results are different. gcc -O0 yields the string length, -O2 and -O3 yield 0.

Maybe the return value of printf is put into the same register as message's would be. And message does not reset the register before returning.

Ronny Brendel
  • 4,777
  • 5
  • 35
  • 55