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

Jon*_*ler 2 c language-lawyer variable-length-array flexible-array-member c11

在C99中,灵活的阵列成员(结构)和可变长度数组是标准的强制性部分 - 符合C99的编译器(实现)必须同时支持它们.

在C11中,允许实现定义(§6.10.8.3条件特征宏):

__STDC_NO_VLA__ 整数常量1,用于指示实现不支持可变长度数组或可变修改类型.

我没有发现标准中的任何地方规定具有FAM的结构是可变修改类型,因此我认为即使不支持VLA,也需要C11编译器来支持FAM.赞成这种解释的一个项目:具有FAM的结构的大小是固定的; FAM不计入大小的一部分(而VLA的大小不是编译时常量).

Sne*_*tel 7

好吧,对于belabor来说显而易见,标准并没有说FAM是可选的,所以FAM不是可选的.

但是,为了更进一步,标准委员会似乎不太愿意接受不支持FAM的实施.与VLA相比,添加对灵活数组的支持是微不足道的 - 稍微调整解析器,允许结构的最后一个成员为大小为零的数组,并将其称为一天.VLA需要更加繁琐的静态分析,并且可能在某些极小的独立架构中实施繁琐或不可能实施.

  • 顺便说一句,我希望委员会有智慧只使用VLA类型声明对象是一个可选功能,同时强制支持可变修改类型.这将允许VLA的主要实际用途,指向VLA的指针. (4认同)
  • @R ..完全同意.在我看来,这是C11的缺陷.Pointer-to-VLA是现代C编程中的一个重要特性.实际分配的VLA实例:不是那么多. (3认同)

das*_*ght 6

灵活的阵列成员支持应独立于VLA支持.事实上,在C99标准给出它们名称之前,可以使用灵活的数组成员,在a的末尾声明一个零长度数组struct.

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

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

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

这些实现点可能非常棘手,以至于编译器设计者决定不实现VLA.

  • C99 之前的结构黑客技术通常涉及大小为 1 的数组。GCC 可能允许大小为 0 的数组;即使标准不这样做,它仍然如此。 (2认同)