Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disable "warning: the address of 'x' will always evaluate as 'true'"

The problem is this:

#define do_stuff(ret) ((ret) ? getstuff(ret) : 0)
int var;
do_stuff(&var);

test.h:34:46: warning: the address of 'var' will always evaluate as 'true' [-Waddress]

do_stuff acts as a function that accepts an output-pointer that can be NULL, though, thus the warning is not helpful but annoying. Is there a way via code to make gcc stop complaining? Maybe an (at least kind of) portable one?

Btw. do_stuff has to be a macro as ret actually gets set in a generic way (here stripped for simplicity).

Edit: Again, I just want to have the usual output-pointer that can be NULL, but inside a macro instead of a function. The actual code looks like this:

#define retrieve(x, ret) \
    ( ret ? (*ret = x.buf[0], 1) : 0 )

which gave the warning from above when using it like retrieve(stuff, NULL). Accordingly to Adriano Repetti's answer, I changed it to:

#define retrieve(x, ret) \
    ( ((void *)ret != NULL) ? (*ret = x.buf[0], 1) : 0 )

which works, but now gives me warning: dereferencing 'void *' pointer as this gets expanded to ( ((void *)NULL != NULL) ? (*NULL = x.buf[0], 1) : 0 ). Is there a way I can get rid of this warning, too?

retrieve has to be a macro because x.buf is of variant type, and so is ret, passing it through a function like in 2501's tip would result in type loss.

like image 443
netcat Avatar asked Nov 20 '14 19:11

netcat


2 Answers

Assuming you really can't avoid a macro and considering that I wouldn't disable warnings (even if this particular one isn't dangerous) then I'd cheat compiler with some casts. Code will be portable and no warnings will be emitted:

#define do_stuff(ret) (((uintptr_t)NULL != (uintptr_t)ret) ? getstuff(ret) : 0)

Central point here is simply this: (uintptr_t)NULL != (uintptr_t)ret. I'd suggest to also read this post here on SO. Note that also simply NULL != (void*)ret works.

like image 200
Adriano Repetti Avatar answered Oct 31 '22 19:10

Adriano Repetti


You can add a dummy function that just returns the pointer, this might silence the compiler:

void* pass( void* a )
{
    return a ;
}

#define do_stuff(ret) ( pass(ret) ? getstuff(ret) : 0)
int var;
do_stuff( &var );
like image 3
2501 Avatar answered Oct 31 '22 20:10

2501