在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。
答案 0 :(得分:2)
允许在数组边界中使用逗号运算符肯定没有歧义。毫无疑问,委员会有理由不允许它,但对于我们这些没有参加讨论的人来说,它只能是猜测。
我推测其中一个动机是避免制造混乱。许多其他语言允许使用以逗号分隔的边界列表声明多维数组,而习惯于其中一种语言的人可能很容易错误地写入int a[2,7];
以获得二维数组。如果允许使用逗号运算符,则会导致声明一个七元素的单维数组,并且不会产生错误消息。尝试索引此类数组时不会产生错误消息,因此编译器会忽略该错误,这可能会被视为不幸。
但那只是一个疯狂的猜测。