Question

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(myFunc)... instead of if(myFunc())...

This did not generate an error neither a warning although I have pretty much every warning turned on.

It simply evaluated to true. Why is this writing legal code in the first place ? Because the function exists/has an address ? Does anyone know how one could avoid such mistakes or if there is a warning option I overlooked ? Is this issue better solved in later gcc versions ?

Here the exact compiler call for completeness:

 msp430-gcc -g -Os -mmcu=msp430x1611 -Wall -W -Wfloat-equal -Wundef -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wwrite-strings -Wsign-compare -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations 
-Wredundant-decls -Wnested-externs -Wimplicit-function-declaration -Werror

(Since I'm forced to use gcc 3.2.3 there is no -Wextra)

Was it helpful?

Solution

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’

OTHER TIPS

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.

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.

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

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.

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