允许在信任边界进行冗余的空指针检查

Han*_*son 6 c static-analysis clang

我最近正在查看一些代码,其中clang会由于产生警告-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 */
   }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

在这种情况下,_In_ _Pre_defensive_最好在信任边界上指出,尽管调用方尝试传递NULL时将收到错误,但将分析函数体,就像参数可能为NULL一样,并且尝试取消引用指针如果没有先检查它是否为NULL,就会被标记。

c可能有类似的东西吗?

Nik*_* C. 4

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

if (true)
Run Code Online (Sandbox Code Playgroud)

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

https://godbolt.org/z/l8w4x1

int func(void* ptr) __attribute__((nonnull))
{
    if (ptr)
        return 1;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

它无条件返回1:

移动eax, 1
雷特

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

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