【问题标题】:Are zero-length variable length arrays allowed/well defined?是否允许/明确定义零长度可变长度数组?
【发布时间】:2013-07-09 22:32:19
【问题描述】:

我正在使用 C99 进行编程,并在我的一部分代码中使用可变长度数组。我知道在 C89 中不允许使用零长度数组,但我不确定 C99 和可变长度数组。

简而言之,以下行为是否明确?

int main()
{
    int i = 0;
    char array[i];
    return 0;
}

【问题讨论】:

  • 这甚至不应该编译,因为i 不是编译时常量。
  • 尝试编译它; gcc 会出来,打你,射你,偷你的车。
  • @Jashaszun:在 C 中,本地数组大小不需要是常数。
  • @TheOtherGuy:C99 中允许使用可变长度数组...

标签: c c99


【解决方案1】:

不,C 语言明确禁止零长度数组,即使它们是通过运行时大小值创建为 VLA(如您的代码示例中所示)。

6.7.5.2 数组声明符

...

5 如果大小是不是整数常量的表达式 表达式:如果它出现在函数原型范围的声明中, 它被视为被 * 替换; 否则,每次都是 评估它应该有一个大于零的值

【讨论】:

  • 噢,是的,引用标准。我喜欢那些。 +1!
【解决方案2】:

零长度数组在 C 中是不允许的。静态类型数组必须有一个固定的、非零大小的常量表达式,而可变长度数组必须有一个非零大小; C11 6.7.6.2/5:

每次计算[大小表达式]时,它的值都应大于零

但是,C99 和 C11 有一个结构体的灵活数组成员的概念:

struct foo
{
    int a;
    int data[];
};

从 C11,6.7.21/18:

作为一种特殊情况,具有多个命名成员的结构的最后一个元素可能 数组类型不完整;这称为灵活的数组成员。在大多数情况下, 灵活的数组成员被忽略。特别是,结构的大小就像 省略了灵活的数组成员,除了它可能有更多的尾随填充 遗漏将意味着。但是,当.(或->)运算符具有左操作数时 (指向)具有灵活数组成员和正确操作数名称的结构 成员,它的行为就好像该成员被替换为最长的数组(具有相同的 元素类型)不会使结构大于被访问的对象;

【讨论】:

  • 感谢有关灵活数组成员的说明。标准中的那句话真的很有用!
【解决方案3】:

标准 C(甚至 C99 或 C11)中不允许使用零长度数组。但是 gcc 确实提供了一个扩展来允许它。见http://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html

 struct line {
   int length;
   char contents[0];
 };

 struct line *thisline = (struct line *)
   malloc (sizeof (struct line) + this_length);
 thisline->length = this_length;

【讨论】:

    猜你喜欢
    • 2012-12-17
    • 2013-08-02
    • 1970-01-01
    • 2012-09-06
    • 2012-01-25
    • 1970-01-01
    • 2014-07-27
    • 2012-05-28
    相关资源
    最近更新 更多