Disable "warning: address" x "will always evaluate to" 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 like a function that accepts an output pointer, which may be NULL, although the warning is thus annoying but not helpful. Is there a way through code to stop gcc from complaining? Maybe (at least one) portable?
Btw. do_stuff
should be a macro since it ret
actually gets the given common path (stripped here for simplicity).
Edit : Again, I just want to have a normal output pointer, which 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 was giving a warning from above using retrieve(stuff, NULL)
. As per 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 it expands to ( ((void *)NULL != NULL) ? (*NULL = x.buf[0], 1) : 0 )
. Is there a way to get rid of this warning?
retrieve
has a macro because x.buf is of a variant type, and thus ret
passing it through a function, for example at tip 2501, will result in type loss.
source to share
Assuming you really can't escape the macro and think that I won't turn off warnings (even if this particular one isn't dangerous), I would trick the compiler with some castes. The code will be portable and no warnings will be issued:
#define do_stuff(ret) (((uintptr_t)NULL != (uintptr_t)ret) ? getstuff(ret) : 0)
The central point here - it's just: (uintptr_t)NULL != (uintptr_t)ret
. I would suggest reading this post here on SO as well. Note that it just works NULL != (void*)ret
.
source to share
As Eugene Sh said, it's better to write your code without warnings,
So instead of this
#define do_stuff(ret) ((ret) ? getstuff(ret) : 0)
void getstuff( int *ptr )
{
printf( "%d\n", *ptr );
}
int main( void )
{
int var = 5;
do_stuff(&var);
}
you could do it
void getstuff( int *ptr )
{
if ( ptr == NULL )
return;
printf( "%d\n", *ptr );
}
int main( void )
{
int var = 5;
getstuff(&var);
}
Better not to hide the validation NULL
in a macro. If the function accepts a pointer that is allowed to be NULL
, then the check NULL
must be explicit in the function itself.
source to share