6

我最近正在查看一些由于-Wtautological-pointer-compare.

代码可以简化为:

void foo(const char*s) __attribute__((nonnull)) {
   if (s) { /* Test added just in case*/
      if (s[0]=='a') s[0]='b'; /* Dummy code using the pointer */
   }
}

显然,如果我们信任这些属性,则s不能为空,并且警告是多余的。但是,对我来说,最好在函数中处理 null-case(因为我们不能相信调用代码是用这些警告编译的,或者人们会阅读警告)——同时仍然检测代码中的其他空指针问题。

因此禁用此警告(对整个函数使用编译指示)似乎不是最佳选择。

在带有 SAL 的 Visual Studio 中,您似乎可以使用它_In_ _Pre_defensive_来处理这种情况。

在这种情况下,_In_ _Pre_defensive_首选在信任边界处指示虽然调用者在尝试传递 NULL 时会收到错误,但函数体将被分析为参数可能为 NULL,并且任何取消引用指针的尝试没有先检查它是否为 NULL 将被标记。

铿锵有类似的可能吗?

4

1 回答 1

4

请注意,这个问题比仅仅看到不需要的警告更糟糕。由于该函数具有该属性,因此编译器将删除 ,if就像您编写的那样:

if (true)

因为你承诺过指针不会NULL。所以你的空检查没有效果。看:

https://godbolt.org/z/l8w4x1

int func(void* ptr) __attribute__((nonnull))
{
    if (ptr)
        return 1;
    return 0;
}

它无条件返回 1:

移动 eax, 1
ret

所以你应该认真对待这个警告。

-fno-delete-null-pointer-checks除了编译以防止空指针检查被优化并-Wno-tautological-pointer-compare消除警告之外,我不知道任何解决方法。显然,您不想全局使用这些标志。因此,您应该将具有此属性的函数合并到它们自己的源文件中,并仅在编译该文件时使用这些标志。

于 2019-07-01T15:13:13.787 回答