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.

+3


source to share


4 answers


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

.

+5


source


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



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

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

      

+2


source


The GCC command line flag -Waddress is used to disable this type of warnings. But it's better to write your code without warning.

+2


source


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.

+1


source







All Articles