Sunday, 30 January 2011

gcc does not check out of scope names in unreachable code

While attempting to write a small HTTP server in C, I copied some code over from a previously written C file and immediately noticed a bug.

File httpd.c
#include "../mynet.h"

if(errno = EINTR) {
    //do something
} else {
    err_sys("read error")
}


Yes it's a stupid beginner mistake - typing the assignment operator instead of the equals check. The thread of execution would never enter the else block. I corrected it, but the interesting part came when I tried to compile it.

cc ../mynet.c httpd.c


mynet.c contains some handy helper functions that I've used in my other server classes. Guess what - the compilation failed with this message


"httpd.c:(.text+0x6a): undefined reference to `err_sys'"


I checked my header and the err_sys function was nowhere to be seen. If this function is missing, how did my other class (from where I copied this code) compile previously?
After some fiddling around I put the assignment operator bug back, and guess what? The code compiled fine.

Based on just these observations, we can conclude that the gcc C compiler ignored the unreachable (else) part of the code. It did not even check if the code inside the else block was legitimate. How far did this behaviour go? Let's see.

File httpd.c
#include "../mynet.h"

if(errno = EINTR) {
    //do something
} else {
    mocha(); //Undefined function
}


This compiles fine.

File httpd.c
#include "../mynet.h"

if(errno = EINTR) {
    //do something
} else {
    asdf;
}


This correctly fails with an error.

So syntax checks are being done in code that is known to be unreachable, but there are no checks for undefined functions. A bug? I would say yes. Google did not turn up much except this old link - http://compgroups.net/comp.lang.c++.moderated/could-if-else-avoid-syntax-checking-compile-time-unreachable-code

No comments:

Post a Comment