我正在研究一个C程序。有一个函数需要两个指针参数,称之为cmp()
。我在此提供了cmp()
的简化替代方案,原因如下:
int cmp(struct foo *a, struct foo *b)
{
return a->bar == b->bar;
}
我想制作一个NULL-check宏,如下所示:
#define SAFE_CMP(a,b) (((a) != NULL && (b) != NULL) ? cmp((a),(b)) : 0)
我认为这很好。但是,在使用-Wall
和将警告视为错误的compliation开关进行编译时,以下代码很麻烦:
int baz(struct foo *a)
{
struct foo b;
/* ... */
return SAFE_CMP(a, &b);
}
因为gcc警告“b的地址永远不会为NULL”。
有没有办法解决这种情况?
拥有像SAFE_CMP_1(safe_arg,unsafe_arg)
和SAFE_CMP_2(unsafe_arg,safe_arg)
等各种辅助宏是我想要的最后一件事。我希望有一个适用于所有情况的辅助宏。
答案 0 :(得分:11)
这似乎压制了我的警告:
#define SAFE_CMP(a,b) (((void *)(a) != NULL && (void *)(b) != NULL) ? cmp((a),(b)) : 0)
......但就个人而言,我只想创建safe_cmp()
作为一个函数。
int safe_cmp(struct foo *a, struct foo *b) {
return (a && b) ? (a->bar == b->bar) : 0;
}
答案 1 :(得分:2)
“我想要一个帮助宏 适用于所有情况。“
为什么呢?一种尺寸并不适合所有人。 GCC通过告诉你比较总是有一定的结果来帮助你。堆栈变量的地址永远不会为NULL。我会写出巴兹的支票:
int baz(struct foo *a) {
struct foo b;
...
return a == NULL ? 0 : cmp(a, &b);
}
您也可以在cmp
中执行此操作。这取决于您如何定义前后条件。
您的宏的另一个可能问题(不适用于baz)是a
和b
将被多次评估。谨防:
SAFE_CMP(p++, p1++);
答案 2 :(得分:0)
gcc 选项-Wno-address
似乎删除了警告。
答案 3 :(得分:-1)
当您收到此类警告时,请考虑是否有可能在if()表达式中出现双重&& &&错误