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

net*_*cat 5 c macros gcc 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]
Run Code Online (Sandbox Code Playgroud)

do_stuff但是,它作为一个函数接受一个可以为NULL的输出指针,因此警告没有用,但很烦人.有没有办法让代码让gcc停止抱怨?也许是(至少是那种)便携式的?

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

编辑:再次,我只想拥有通常的输出指针,它可以是NULL,但在宏而不是函数内.实际代码如下所示:

#define retrieve(x, ret) \
    ( ret ? (*ret = x.buf[0], 1) : 0 )
Run Code Online (Sandbox Code Playgroud)

当使用它时,它从上面发出警告retrieve(stuff, NULL).根据Adriano Repetti的回答,我将其更改为:

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

这有用,但现在给了我,warning: dereferencing 'void *' pointer因为它扩展到( ((void *)NULL != NULL) ? (*NULL = x.buf[0], 1) : 0 ).有没有办法可以摆脱这个警告呢?

retrieve 必须是一个宏,因为x.buf是变体类型,因此ret,通过像2501的提示中的函数传递它将导致类型丢失.

Adr*_*tti 7

假设你真的无法避免一个宏,并考虑到我不会禁用警告(即使这个特定的没有危险),那么我会欺骗编译器与一些演员.代码将是可移植的,不会发出警告:

#define do_stuff(ret) (((uintptr_t)NULL != (uintptr_t)ret) ? getstuff(ret) : 0)
Run Code Online (Sandbox Code Playgroud)

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

  • @ 2501 gcc 4.8.1,我也喜欢你的方法:它引入了一个假函数但它会被优化掉(一般而言,特别是对于宏,可能会隐藏可怕的错误) (2认同)
  • 指向同一对象的两个指针可能具有不同的位表示.然而,这两个指针的比较`=='将产生真实.唉,当这两个指针转换为uintptr_t时,这两个整数的比较`=='可能不会产生真.这不会发生在您正在使用的体系结构上,但C允许这样的体系结构,这意味着此代码将无法在此类体系结构上正常运行. (2认同)