【问题标题】:What are the differences between Variable Length Arrays and Flexible Array Member?可变长度数组和灵活数组成员有什么区别?
【发布时间】:2016-03-02 22:01:09
【问题描述】:

我在ISO C99 committee draft 中看到,结构可以有一个不完整的数组,其末端未指定大小,称为灵活数组成员。

另一方面,C99 也有可变长度数组,它允许在编译时声明大小不恒定的数组。

我认为 FAM 是一种特殊的 VLA,但我看到两个 SO 用户声称并非如此。此外,阅读Wikipedia section on sizeof,它说sizeof 对这两者的行为不同。

为什么它们都存在而不是只有一个? (他们的用例是不是太不同了?)

另外,还有哪些其他相关行为对于它们每个是不同的?

【问题讨论】:

  • 维基百科关于sizeof 是正确的。 VLA 的大小是运行时计算的值——与所有其他出现的sizeof 不同。包含 FAM 的结构的大小在编译时是固定的,不包括 FAM 的大小。

标签: c c99 variable-length-array flexible-array-member


【解决方案1】:

C99 标准添加了两个不同的东西,很容易混淆:

灵活的数组成员。这意味着结构可以在末尾有一个未知大小的成员。来自 C 标准的示例:

    struct s { int n; double d[]; };

int m = /* some value */;
struct s *p = malloc(sizeof (struct s) + sizeof (double [m]));

这在 C99 之前也使用过,但当时是未定义的行为,称为另一个答案中提到的“struct hack”。在 C90 之前,结构末尾可能会有意外的填充字节,从而导致错误。

可变长度数组 (VLA)。 这些是在运行时设置大小的数组。它们很可能是由编译器通过使用动态内存分配来实现的。示例:

void func (int n)
{
  int array[n];
}

来自user29079:https://softwareengineering.stackexchange.com/questions/154089/c-flexible-arrays-when-did-they-become-part-of-the-standard

【讨论】:

  • 但是为什么有人会使用第一个而不是第二个呢?是不是不能用VLA作为struct成员?
  • @VillasV:是的,不可能在结构中使用 VLA。必须在编译时知道结构的大小。 FAM 不计入结构的大小,但它们可能会影响结构中的填充量。
  • 灵活的数组成员并不能代表一个新特性,而是它们代表了对原本不应该存在的限制的部分放宽。在 C89 之前,许多编译器会将大小为零的数组声明视为创建指向第一个数组元素所在位置的指针,但不会为数组分配空间,这就是编译器通常处理灵活数组成员的方式。允许编译器以稍微不同的方式处理灵活的数组成员,但我认为如果标准只是允许这些成员不会发生变化......
  • ...从零开始的数组声明。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多