5

Why this piece of code compiles?

#include <iostream>

int foo(int x)
{
   if(x == 10)
     return x*10;
}

int main()
{
int a;
std::cin>>a;
std::cout<<foo(a)<<'\n';
}

The compiler shouldn't give me an error like "not all code paths returns a value"? What happens/returns my function when x isn't equal to ten?

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • Not strictly related, but may pique your interest: http://stackoverflow.com/questions/9653722/how-does-returning-values-from-a-function-work – Corbin Mar 16 '12 at 17:57
  • BTW: what compiler is this (so that I can avoid it in the future)? – Nicol Bolas Mar 16 '12 at 17:57
  • 1
    @NicolBolas: Don't avoid the compiler, avoid compiling without warn-flags! – bitmask Mar 16 '12 at 17:59
  • 1
    @bitmask: That kind of flag should be on by *default*. Just like warnings about `if(x = 5)` and other common mistakes that are syntactically legal. – Nicol Bolas Mar 16 '12 at 18:01
  • @NicolBolas: Not necessarily! There could be cases where the non-returning branch is impossible to reach at runtime, but the compiler cannot determine that. Also the compiler vendor is supposed to choose which warnings to emit on default (I would also prefer compilers to be more verbose at default, but that's why you can pass it `-Wall -Wextra -pedantic`). – bitmask Mar 16 '12 at 18:04
  • @bitmask: Yes, just as there are cases where `if(x = 5)` is legitimate. However, it is more likely to be a *mistake* than deliberate behavior. And the compiler should default to pointing that out. All it takes is a simple return statement at the bottom to shut the compiler up. – Nicol Bolas Mar 16 '12 at 18:21
  • @NicolBolas: Unless you are returning a complex that cannot be constructed in the unreachable case. – bitmask Mar 16 '12 at 18:31
  • @NicolBolas - a small survey: `g++` 4.6.1 doesn't warn on this by default, but adding `-Wall` does. MSVC warns by default (at least as far back as VC++6), as does Digital Mars. – Michael Burr Mar 16 '12 at 19:07
  • Your function `foo` is to return an `int`. This is true if the `if` statement holds. Otherwise what value is to be returned by `foo`? – Ed Heal Mar 16 '12 at 17:55
  • That's what he's asking; what gets returned. – Nicol Bolas Mar 16 '12 at 17:56
  • I think he's asking why it *does* compile, when it doesn't always obviously return a value. – cHao Mar 16 '12 at 17:57
  • I was pointing the person as to why it will not compile. You can sometimes ask a question to get a person to be able to see something that they have missed. – Ed Heal Mar 16 '12 at 18:00
  • But it *does* compile for him. And now he's wondering how/why, and he's asking the very question you did. If he didn't see what he missed when he was typing the question, seeing it repeated to him won't do much good... :) – cHao Mar 16 '12 at 18:05
  • Eh? I quote *The compiler shouldn't give me an error like "not all code paths returns a value* in the OP. That implies that the compiler is giving an error. – Ed Heal Mar 16 '12 at 18:14
  • Take a closer look. _The compiler shouldn't give me an error like "not all code paths returns a value"?_ That question mark changes the meaning from "it shouldn't" to "shouldn't it?". And the question right after that looks quite a bit like the one you just posed back to him, which he wouldn't have thought to ask if the code didn't compile. – cHao Mar 16 '12 at 18:17
  • @EdHeal: And "Why this piece of code compiles?" directly states that it *does* compile. The OP is obviously not a native English speaker, so missing a word or grammer here or there is not unexpected. – Nicol Bolas Mar 16 '12 at 18:24
  • @cHao - He is questioning the compiler giving the error. The second question is asking what the code would do if it **did** compile. that was my understanding. The question that I posed was to get the person to where to look to find out why it does not compile. BTW - I am English and we invented the language :-> – Ed Heal Mar 16 '12 at 18:26
  • @EdHeal: Eh. I'm American. We perfected it. :) But if you look, you'll see that question was actually the third. See the first question, right at the top of the post. No ambiguity there. – cHao Mar 16 '12 at 18:29
  • @cHao - That is a grey (NOT GRAY) area. What the hell happened on the Mayflower? – Ed Heal Mar 16 '12 at 18:35

2 Answers2

10

The result is undefined, so the compiler is free to choose -- you probably get what happens to sit at the appropriate stack address where the caller expects the result. Activate compiler warnings, and your compiler will inform you about your omission.

bitmask
  • 32,434
  • 14
  • 99
  • 159
  • Calling a function that should return something but doesn't, can cause a beautiful crash on some systems. – karlphillip Mar 16 '12 at 17:57
  • 1
    @karlphillip: Yes, because the compiler is legally allowed to burn your house down or make dragons fly out your nose. That's why I added the word *probably* :) – bitmask Mar 16 '12 at 17:59
  • I noticed :) I added a comment just to point out how bad can this practice be. Nice answer, by the way. – karlphillip Mar 16 '12 at 18:00
  • Ok. But this seems strange because i remember that the compiler should give me an error, not a simple warning. I'm surprised that give me just a warning. (btw, i've tried g++ and msvc++. Both are behaving the same way). Probabily the c++ standard says that the result is undefined :O ) – MasterChief Mar 16 '12 at 18:06
  • 1
    @MasterChief: In Java, C# and such as that, this would always be an error. In C and C++, not so much. Some compilers will throw an error, most just a warning. The compiler typically assumes you know what you're doing, though, so it won't get in your way unless you're doing something that's blatantly against the rules. And it's not illegal to ask for trouble. :) – cHao Mar 16 '12 at 18:12
  • @bitmask, can I get a link to the dragon-producing compiler? That sounds cool! – AShelly Mar 16 '12 at 18:13
  • @AShelly: Sorry, it was *demons*, not *dragons*: http://www.catb.org/jargon/html/N/nasal-demons.html – bitmask Mar 16 '12 at 18:18
  • @MasterChief not necessarily... Sometimes you want compilers to not do anything "creative", especially if you know the outlying architecture and there is some external volatility control on whatever is going on – Ahmed Masud Mar 16 '12 at 18:38
3

The compiler is not required to give you an error in this circumstance. Many will, some will only issue warnings. Some apparently won't notice.

This is because it's possible that your code ensures outside of this function that the condition will always be true. Therefore, it isn't necessarily bad (though it almost always is, which is why most compilers will issue at least a warning).

The specification will state that the result of exiting a function that should return a value but doesn't is undefined behavior. A value may be returned. Or the program might crash. Or anything might happen. It's undefined.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982