如何解决 GCC 警告“XXX 的地址永远不会为 NULL”?

发布于 2024-09-07 22:30:48 字数 718 浏览 7 评论 0原文

我正在开发一个 C 程序。有一个函数需要两个指针参数,称之为cmp()。出于说明原因,我在这里展示了 cmp() 的简化替代品:

int cmp(struct foo *a, struct foo *b)
{
    return a->bar == b->bar;
}

我想制作一个 NULL 检查宏,如下所示:

#define SAFE_CMP(a,b) (((a) != NULL && (b) != NULL) ? cmp((a),(b)) : 0)

我认为这完全没问题。然而,当同时使用 -Wall 和将警告视为错误的编译开关进行编译时,以下代码会很麻烦:

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) 等各种辅助宏。我想要一个适用于所有情况的辅助宏。

I'm working on a C program. There is a function which takes two pointer arguments, call it cmp(). I present here a simplified stand-in for cmp() for illustrative reasons:

int cmp(struct foo *a, struct foo *b)
{
    return a->bar == b->bar;
}

I'd like to make a NULL-check macro, like this:

#define SAFE_CMP(a,b) (((a) != NULL && (b) != NULL) ? cmp((a),(b)) : 0)

I think this is perfectly fine. However, in when compiling with both -Wall and a compliation switch that regards a warning as an error, the following code is troublesome:

int baz(struct foo *a)
{
   struct foo b;
   /* ... */
   return SAFE_CMP(a, &b); 
}

since gcc warns that "the address of b will never be NULL".

Is there any way to workaround this situation?
Having various helper macro like SAFE_CMP_1(safe_arg,unsafe_arg) and SAFE_CMP_2(unsafe_arg,safe_arg) etc. is the last thing I want. I'd like to have one helper macro applicable to all situations.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

南笙 2024-09-14 22:30:48

这似乎压制了我的警告:

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

This seems to suppress the warning for me:

#define SAFE_CMP(a,b) (((void *)(a) != NULL && (void *)(b) != NULL) ? cmp((a),(b)) : 0)

...but personally, I would just create safe_cmp() as a function itself.

int safe_cmp(struct foo *a, struct foo *b) {
    return (a && b) ? (a->bar == b->bar) : 0;
}
×眷恋的温暖 2024-09-14 22:30:48

“我想要一个辅助宏
适用于所有情况。”

为什么?一种方法并不适用于所有情况。GCC 告诉您比较将总是得到某个结果,这是对您的帮助。堆栈变量的地址将永远不会为 NULL。我只会在 baz 中写出检查:

int baz(struct foo *a) {
   struct foo b;
   ...
   return a == NULL ? 0 : cmp(a, &b);
}

您也可以在 cmp 中执行此操作,这取决于您如何定义前置条件和后置条件

。宏(不适用于 baz)是 ab 将被评估多次。

SAFE_CMP(p++, p1++);

"I'd like to have one helper macro
appricable to all situation."

Why? One size does not fit all. GCC is doing you a favor by telling you a comparison will always have a certain result. The address of a stack variable will never be NULL. I would just write out the check in baz:

int baz(struct foo *a) {
   struct foo b;
   ...
   return a == NULL ? 0 : cmp(a, &b);
}

You could also do it in cmp. It depends how you define the pre and post-conditions.

Another possible issue with your macro (not applicable for baz) is that a and b will be evaluated multiple times. Beware of:

SAFE_CMP(p++, p1++);
终止放荡 2024-09-14 22:30:48

gcc 选项 -Wno-address 似乎删除了警告。

The gcc option -Wno-address seems to remove the warnings.

生生漫 2024-09-14 22:30:48

当您收到此类警告时,请考虑您有双重 && 的可能性。 && if () 表达式中有错误

When you have such warning consider possibility you have double && && mistake in your if () expression

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文