I recently stumbled across the following behaviour of gcc 3.2.2 writing a c program:
In an if statement I forgot the braces of a function and wrote:
if
Pointers to functions are sometimes useful - as callbacks eg in sort routines or data capture. Or for doing optimized calculated-goto type routines, since C doesn't have templates.
But 99% of the time it's an error, newer compilers will warn you
myFunc
, since its the name of a function will always evaluate to true
because its a pointer. More specifically it has to be a non-null pointer because you will be needing to dereference it. A null
pointer would evaluate to false
.
In short, there does not seem to be a way for the compiler to tell you that you've made a mistake.
What you need to do is to have some unit tests that separately invoke the true
and false
responses so that you can tell that you've actually called the function.
if (myFunc)
is equivalent to if (&myFunc)
, so you're testing the address of a function, which of course will always be non-zero, i.e. true.
With gcc 4.2.1 and -Wall
I get the following warning:
myfunc.c:11: warning: the address of ‘myFunc’ will always evaluate as ‘true’
myFunc
is simply the memory address of the function, and is non-zero.
Your if-statement is pretty much the same as writing:
if (0x08451234) { ... }
And as a non-zero value, it is true
.
No warning seems appropriate, as it is valid and even somewhat common to test function-pointers to see if they are NULL or not.
This is to support an old linker hack; many compilers/linkers (including gcc and GNU binutils) allow you to define a weak symbol for a function which evaluates to 0 unless another object file/shared library that got linked overrides the value of the symbol. glibc makes use of this trick for some version-compatibility hacks.