问题在于:
#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>的提示会导致类型丢失。
答案 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
检查应该在函数本身中显式。