为什么任意表达式不能用作数组大小,例如INT [0,1]?

时间:2015-03-01 01:02:55

标签: c arrays grammar c99 variable-length-array

static括号中忽略*[](对于省略的大小),数组声明符的语法是(来自C99 TC3(n1256)6.7.5 p1; C11(n1570)6.7.6 p1):

  

direct-declarator: direct-declarator [ type-qualifier-listopt assignment-expressionopt ] [...]

因此,声明如

int foo[0,1];

是语法错误,但

int foo[(0,1)];
允许

(在块范围内,因为这是VLA)。

在某些情况下,不允许使用任意表达式,因为这会导致使用逗号作为分隔符时出现歧义。例如,函数调用的参数必须是赋值表达式。但是,我不知道

是如何造成这种歧义的

direct-declarator: direct-declarator [ type-qualifier-listopt expressionopt ]

这会定义C语言的严格超集吗?是否存在这种语法含糊不清的例子?

C89 *)在语法中需要常量表达式(这是条件表达式)所以需要将C99更改为允许VLA。但我不明白为什么它被改为赋值表达式而不是表达式。有技术原因吗?

Gcc(可能还有其他编译器)在将VDA添加到C标准之前将其作为扩展,与其他扩展的冲突也可能是一种解释,但我不知道这样的扩展。 Gcc 3.0.4接受int a[0,1];-std=gnu89-traditional),新版本(使用Gcc(Debian)4.7.2-5进行测试)不是,所以这看起来不太可能成为原因。

据我所知,这个问题等同于类型名称中的直接抽象声明符

*)根据this C89 draft,3.5.4。

1 个答案:

答案 0 :(得分:2)

允许在数组边界中使用逗号运算符肯定没有歧义。毫无疑问,委员会有理由不允许它,但对于我们这些没有参加讨论的人来说,它只能是猜测。

我推测其中一个动机是避免制造混乱。许多其他语言允许使用以逗号分隔的边界列表声明多维数组,而习惯于其中一种语言的人可能很容易错误地写入int a[2,7];以获得二维数组。如果允许使用逗号运算符,则会导致声明一个七元素的单维数组,并且不会产生错误消息。尝试索引此类数组时不会产生错误消息,因此编译器会忽略该错误,这可能会被视为不幸。

但那只是一个疯狂的猜测。