3

Please explain why sometimes return statement is not needed?

Function has a return type, but return statement missing. Meanwhile, program compiles and works fine.

Please help me understand this better

char* handleInput() {
    fgets(buffer, 1024, stdin);
//    return buffer;       <---- COMMENTED RETURN
}

void main() {
        char* ptr = handleInput();
        int flag = atoi(ptr);    
        if (flag < 0) break;    
        printf("You entered: %s\n", ptr);
}
Marco Bonelli
  • 63,369
  • 21
  • 118
  • 128
James Raitsev
  • 92,517
  • 154
  • 335
  • 470

3 Answers3

13

Basically what gets returned is dumb luck. You get what happens to be in the CPU register when it comes back. If, for example, the returned value would be in AX, and the char* happens to be in AX, you lucked out. I believe this is an undefined behavior; i.e. the C language specifications don't tell what you should so, so it is left to the compiler. I'm surprised a modern compiler wouldn't at least throw a warning at you.

Aaron D. Marasco
  • 6,506
  • 3
  • 26
  • 39
  • Yup. I expected a warning as well. GCC was fine with this code. No warnings – James Raitsev Jul 10 '11 at 03:28
  • 1
    compile with `gcc -W -Wall -ansi -pedantic` and you will see warnings. – Alok Singhal Jul 10 '11 at 03:30
  • 1
    I'm sure the warning was present. The dumb luck is very likely because fgets actually returns buffer, which is almost assuredly already in the return register, which is RAX or EAX on Intel boxes (they stopped using AX in 1985 :) ). Because it was the last statement executed in handleInput, handleInput returns and what is in the return register? That's right -- buffer! You can look at the generated assembly language to see this. Also @mac, did you compile with warnings turned on? – Ray Toal Jul 10 '11 at 03:30
  • @Ray Toal - Thanks for the update, I'm not an assembly guy ;) – Aaron D. Marasco Jul 10 '11 at 03:32
5

C99 6.9.1/12 "Function definitions" says:

If the } that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined.

C90 6.6.6.4 "The return statement"standard says something with simialr effect:

If a return statement without an expression is executed, and the value of the function call is used by the caller, the behavior is undefined. Reaching the } that terminates a function is equivalent to a return statement without an expression.

So returning from a function without returning something from the function is permitted - but the caller of the function isn't allowed to use the 'result' of the function call. That's undefined behavior, and like other answers have mentioned you can get 'expected' results with undefined behavior, but that's only by chance.

I believe the rationale for this is that pre-standard C defaulted to a return type of int for functions if the function wasn't explicitly declared (or if the declaration omitted the return type), and that continued to be supported when C was standardized. Many of those functions were designed to be called only for side-effects they produced, and no return value was expected or provided.

A couple side notes:

  • gcc will warn about this if the -Wall option is used. MSVC warns about it by default.
  • you should be getting a compiler error about the if (flag < 0) break; line since the break isn't in a loop or switch.
  • main() should return int not void (-Wall will warn about that as well). Of course, you should also return some value explicitly...
Michael Burr
  • 333,147
  • 50
  • 533
  • 760
-1

Not using 'return' in a function declared to return a value is bad practice to say the least. Most compilers should generate a warning.

seand
  • 5,168
  • 1
  • 24
  • 37