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的提示中的函数传递它将导致类型丢失.
假设你真的无法避免一个宏,并考虑到我不会禁用警告(即使这个特定的没有危险),那么我会欺骗编译器与一些演员.代码将是可移植的,不会发出警告:
#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.