Question

Okay, little oddity I discovered with my C++ compiler.

I had a not-overly complex bit of code to refactor, and I accidentally managed to leave in a path that didn't have a return statement. My bad. On the other hand, this compiled, and segfaulted when I ran it and that path was hit, obviously.

Here's my question: Is this a compiler bug, or is there no guarantee that a C++ compiler will enforce the need for a return statement in a non-void return function?

Oh, and to be clear, in this case it was an unecessary if statement without an accompanying else. No gotos, no exits, no aborts.

Was it helpful?

Solution

Personally I think this should be an error:

int f() {
}

int main() {
    int n = f();
    return 0;
}

but most compilers treat it as a warning, and you may even have to use compiler switches to get that warning. For example, on g++ you need -Wall to get:

[neilb@GONERIL NeilB]$ g++ -Wall nr.cpp
nr.cpp: In function 'int f()':
nr.cpp:2: warning: no return statement in function returning non-void

Of course, with g++ you should always compile with at least -Wall anyway.

OTHER TIPS

There is no guarantee that a C++ compiler will enforce that. A C++ function could jump out of its control flow by mechanisms unknown to the compiler. Context switches when C++ is used to write an OS kernel is an example of that. An uncaught exception thrown by a called function (whose code isn't necessarily available to the caller) is another one.

Some other languages, like Java, explicitly enforce that with knowledge available at compile time, all paths return a value. In C++ this isn't true, as is with many other occasions in the language, like accessing an array out of its bounds isn't checked either.

The compiler doesn't enforce this because you have knowledge about what paths are practically possible that the compiler doesn't. The compiler typically only knows about that particular file, not others that may affect the flow inside any given function. So, it isn't an error.

In Visual Studio, though, it is a warning. And we should pay attention to all warnings.... right? :)

Edit: There seems to be some discussion about when this could happen. Here's a modified but real example from my personal code library;

enum TriBool { Yes, No, Maybe };

TriBool GetResult(int input) {
    if (TestOne(input)) {
        return Yes;
    } else if (TestTwo(input)) {
        return No;
    }
}

Bear with me because this is old code. Originally there was an "else return maybe" in there. :) If TestOne and TestTwo are in a different compilation unit then when the compiler hits this code, it can not tell if TestOne and TestTwo could both return false for a given input. You, as the programmer that wrote TestOne and TestTwo, know that if TestOne fails then TestTwo will succeed. Maybe there are side effects of those tests so they have to be done. Would it be better to write it without the "else if"? Maybe. Probably. But the point is that this is legal C++ and the compiler can't know if it is possible to exit without a return statement. It is, I agree, ugly and not good coding but it is legal and Visual Studio will give you a warning but it will compile.

Remember that C++ isn't about protecting you from yourself. It is about letting you do what your heart desires within the constraints of the language even if that includes shooting yourself in the foot.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top