c - 为什么 [static AND] 在编译时不强制执行?

标签 c arrays language-lawyer c99

C99 添加了static在函数参数中(仅在函数定义中有意义,而不是声明中):

void func( int a[static 10] )
{
    if ( a == NULL )
       { /* this branch can be optimized out */ }

    printf("%d", a[-1]);    /* causes UB */
}

但是,它的含义在 C11 6.7.6.3/7 中定义为语义,而不是约束,这意味着如果函数调用不正确。事实上,编译器绝不能中止编译,除非它可以证明 UB 是在所有分支中引起的。例如:

int main()
{
    func(NULL);   // UB

    int b[9];
    func(b);      // UB
}

为什么标准没有将此作为约束(因此需要诊断)?

第二个问题:为什么 static 在原型(prototype) (6.7.6.3/13) 中被忽略,而不是成为函数签名的一部分?允许原型(prototype)包含它但函数体不包含它似乎具有误导性,反之亦然。

最佳答案

因为在所有情况下都无法在编译时检测到违规。

例如,参数可以是指向用 malloc() 分配的数组的初始元素的指针。编译器通常无法确定数组的大小。如果参数是指针对象,编译器也不能检测它是否为 null。

此功能的主要目的不是强制限制调用,而是启用优化。编译器可能假设参数指向指定长度数组的初始元素。在某些情况下,这可以实现更好的代码生成。

但是编译器肯定可以对它们可以检测到的情况发出非致命警告。标准中没有暗示不应发出此类警告。

关于c - 为什么 [static AND] 在编译时不强制执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29090710/

相关文章:

python - 如何计算矩阵各行的加权平均值,但每行的权重不同?

c# - 为什么具有带有类型参数 P 的泛型结构字段的结构 P 会导致 TypeLoadException

c++ - 我们是否仍然需要单独定义静态成员,即使它们是在类定义中初始化的?

c - c 中的 gethostbyname() 替代品

javascript - 将数组添加到哈希表

c - 如何找到数组中存在的项目的长度/数量?

c - 具有包含对静态对象的引用的外部链接的内联函数定义

c - 是否可以 Hook 任何时间检索功能

c# - 我如何将此加密从 C# 转换为 C

c - C 中结构中的 char 数组的 strcpy 问题