如果编译器定义了__STDC_NO_VLA__,它是否还必须支持灵活的数组成员?

时间:2018-07-01 15:29:28

标签: c language-lawyer c11 variable-length-array flexible-array-member

在C99中,(结构的)柔性数组成员和可变长度数组是标准的必需部分—符合标准的C99编译器(实现)必须同时支持它们。

在C11中,允许实现定义(§6.10.8.3 Conditional feature macros):

  

__STDC_NO_VLA__整数常量1,旨在表示   实现不支持可变长度数组或可变   修改类型。

我没有在标准中发现任何带有FAM的结构是可变修改类型的标准,因此我认为即使不支持VLA,也需要C11编译器来支持FAM。支持这种解释的一项是:带有FAM的结构的大小是固定的; FAM不算作大小的一部分(而VLA的大小不是编译时常数)。

2 个答案:

答案 0 :(得分:6)

好吧,很明显,该标准没有说FAM是可选的,所以FAM不是可选的。

不过,要想走得更远,标准委员会似乎不太可能愿意接受不支持FAM的实施。与VLA相比,增加对灵活数组的支持是微不足道的-稍微调整解析器,使结构的最后一个成员成为零大小的数组,然后将其命名为day。 VLA需要更多复杂的静态分析,在某些小型独立式架构中可能会繁重或不可能实现。

答案 1 :(得分:5)

灵活的阵列成员支持应独立于VLA支持。实际上,在C99标准通过在struct的末尾声明零长度数组来给它们命名之前,可以使用灵活的数组成员。

基本上,要支持灵活的数组成员,唯一要做的就是更改编译器以支持flexible[]语法。

相反,支持VLA需要付出更多努力:

  • 在编译时可能不再进行自动分配
  • sizeof运算符必须更改为支持运行时评估
  • 必须设计特殊的结构以保持可用的阵列大小

对于编译器设计者来说,这些实现点可能非常棘手,他们决定不实现VLA。