为什么[静态N]在编译时没有强制执行?

时间:2015-03-17 03:14:29

标签: 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在原型(6.7.6.3/13)中被忽略,而不是作为功能签名的一部分?允许原型包含它但功能体不包含它似乎有误导性,反之亦然。

1 个答案:

答案 0 :(得分:5)

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

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

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

但编译器当然可以针对他们可以检测到的案例发出非致命警告。标准中没有暗示不应发布此类警告。