禁用"警告:' x'的地址将始终评估为' true'"

时间:2014-11-20 19:45:54

标签: c gcc macros compiler-warnings suppress-warnings

问题在于:

#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充当接受可以为NULL的输出指针的函数,因此警告没有帮助但令人讨厌。 有没有办法让代码让gcc停止抱怨?也许是(至少是那种)便携式的?

顺便说一下。 do_stuff必须是一个宏,因为ret实际上是以通用方式设置的(为简单起见,这里为了剥离)。

修改: 同样,我只想拥有通常的输出指针,它可以是NULL,但在宏而不是函数内。实际代码如下所示:

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

在使用retrieve(stuff, NULL)时使用上面的警告。根据 Adriano Repetti 的回答,我将其更改为:

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

有效,但现在为warning: dereferencing 'void *' pointer提供了( ((void *)NULL != NULL) ? (*NULL = x.buf[0], 1) : 0 ),因为它已扩展为retrieve。有没有办法摆脱这个警告呢?

ret 是一个宏,因为x.buf属于变体类型,{{1}}也是如此,通过 2501 <中的函数传递它/ em>的提示会导致类型丢失。

4 个答案:

答案 0 :(得分:6)

假设你真的无法避免使用宏,并且考虑到我不会禁用警告(即使这个特定的警告不是危险的),那么我就是这样做的。带有一些演员的d 作弊编译器。代码将是可移植的,不会发出警告:

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

这里的中心点就是:(uintptr_t)NULL != (uintptr_t)ret。我建议也在这里阅读this post。请注意,NULL != (void*)ret也很简单。

答案 1 :(得分:2)

你可以添加一个只返回指针的虚函数,这可能会使编译器静音:

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

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

答案 2 :(得分:2)

GCC的-Waddress命令行标志用于禁用此类警告。但最好在没有警告的情况下编写代码。

答案 3 :(得分:1)

正如Eugene Sh所说,最好在没有警告的情况下编写代码,

所以不是这个

#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);
}

你可以这样做

void getstuff( int *ptr )
{
    if ( ptr == NULL )
        return;

    printf( "%d\n", *ptr );
}

int main( void )
{
    int var = 5;
    getstuff(&var);
}

最好不要隐藏宏中的NULL支票。如果函数采用允许为NULL的指针,则NULL检查应该在函数本身中显式。