__attribute__((nonnull)) 在 C 中是否标准化

Tri*_*waj 2 c compiler-errors

我想知道__attribute__((nonnull))是 C 中的标准还是编译器特定的。如果它是特定于编译器的,那么是否有其他替代方法可以与标准 C 做同样的事情?

我试图阻止静态分析器可能的空指针取消引用警告,但我不想让我的代码编译器依赖。

PSk*_*cik 7

它是特定于编译器的。C11 标准中的任何地方都没有提到属性和非空值。

在 C11 中,您可以使用类型 ParameterName[static 1]语法,尽管只有clangzapcc(在gcc <= 7.1 和clang >= 3.1、zapccicc 之外)会在您将 NULL 参数传递给它时生成警告。(此外,不幸的是,它不能与指针一起使用)。

__attribute__((__nonnull__)) /*nonstandard*/
void pass_nonnull0(char *X)
{
}

void pass_nonnull1(char X[static 1]) /*standard*/
{ /*the "static 1" means the pointed-to "array" must have at least 1 element*/
}

int main()
{
    pass_nonnull0(0); /* both clang & gcc warn with nonnull attributes */
    pass_nonnull1(0); /* only clang and zapcc warn with type ArgName [static 1] */
}
Run Code Online (Sandbox Code Playgroud)

的的语义 d [静态类型限定符listopt赋值表达式]语法真的不保证警告。该语法仅表示对编译器的承诺,即指向的对象将至少具有 N 个元素:

6.7.6.3p7

将参数声明为“类型数组”应调整为“指向类型的限定指针”,其中类型限定符(如果有)是在数组类型派生的 [ 和 ] 中指定的那些。如果关键字 static 也出现在数组类型派生的 [ 和 ] 中,那么对于函数的每次调用,相应实参的值应提供对数组的第一个元素的访问,该元素至少与指定的元素一样多由大小表达式。

但是,如果编译器可以看到承诺被破坏,则生成警告是明智的。


Mec*_*cki 6

__attribute__(...)从来都不是标准 C。甚至没有定义存在的
C 标准。__attribute__