Thursday 1 September 2011

GCC No Return Errors

Most of the time that I'm writing C/C++ code, I expect that my compiler will just "do the right thing". Ran into an interesting problem which highlights just how naive that can be, and started looking into strategies for preventing this problem and ones like it in the future.

In C++ it is permissible to omit a return statement from a functions that have been declared with non-void return types. For example, in the following code, the function bar omits the return. This however, is getting into the realms of undefined behavior

struct Foo { 
    int a;
    int b;
};

Foo bar() { 
    // missing return
}

int main() {
    Foo f = bar();
    return 0;
}

By default compiling that snippet of code using gcc:

g++ -c snippet.cpp

gives no warnings at all. Most of the time, I'm careful enough to at least compile with warnings enabled (-Wall)

> g++ -Wall -c snippet.cpp
snippet.cpp: In function ‘Foo bar()’:
snippet.cpp:8: warning: no return statement in function returning non-void

which is at least a helpful warning message. However, at times it can be fairly easy to ignore warnings, and this is where I got bitten. The no return statement warning was hidden amongst warnings being generated by third party library code, and I (wrongly!) assumed that it wasn't important.

I'd prefer that this didn't happen again in the future. GCC has a -Werror flag that will convert all warnings to errors, but in my case, I'd prefer fast development cycles to having perfectly clean and portable code (at least for prototyping).

Turning to stackoverflow I found a method for converting the warning to an error, and in the process learned how to use gcc warning names and diagnostics. The final solution is to use -Werror=, and in this case -Werror=return-type.

g++ -Werror=return-type -Wall -c snippet.cpp
snippet.cpp: In function ‘Foo bar()’:
snippet.cpp:8: error: no return statement in function returning non-void

The side-effect of doing this highlighted how important it will be in the future to consistently (but selectively) start to force myself to deal more rigorously with warnings. Again, stackoverflow to the rescue to identify the flags that are most likely to help.

It's probably worth noting that under MSVC, this warning is automatically promoted to an error by default

2 comments:

  1. I was going to say that I'm sure I remember a compiler complaining to me for this... but it was the MSVC compiler!

    Good advice to check all warnings though. I sometimes look at the warnings from libraries (such as the classics related to initialisations of char* that always pop up) and put in specific ignores for those warnings...

    My worry is that I wont know what warnings to elevate to error status... So I'll miss something

    ReplyDelete
  2. -W -Wall -Wextra -Wwrite-strings -Wcast-qual -pedantic -Wconversion

    How can you not :P

    ReplyDelete