【问题标题】:Why is [static N] not enforced at compile-time?为什么 [static AND] 在编译时不强制执行?
【发布时间】:2015-05-19 09:17:09
【问题描述】:

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) 中被忽略,而不是作为函数签名的一部分?允许原型包含它但函数体不包含它似乎具有误导性,反之亦然。

【问题讨论】:

  • int *p = create_array(); func(p);你如何诊断这个?
  • 对于 q2,数组声明符中的static 不是存储类说明符,因此 6.7.6.3/13 不适用。参照。 6.7.6.3/2 - “唯一应该出现在参数声明中的存储类说明符是register。”
  • @TC 重新。 q2:好的,这是否意味着它在原型中实际上很重要?

标签: c arrays language-lawyer c99


【解决方案1】:

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

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

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

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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2014-11-05
  • 1970-01-01
  • 2019-03-07
  • 1970-01-01
  • 1970-01-01
  • 2020-06-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多