我刚刚注意到
int arr2[(777, 100)]
是合法的数组声明符,而 int arr1[777, 100]
不是。
一个更详细的编译示例是这样的
#include <stdio.h>
void f(int i) {
printf("side effect %d\n", i);
}
int main(void) {
// int arr1[777, 100]; // illegal, it seems
int arr2[(777, 100)];
int arr3[(f(777), 100)];
arr2[10, 20] = 30;
arr3[f(40), 50] = 60;
return 0;
}
它可以与 GCC 编译良好(但由于某种原因不能与 MSVC 编译)。
还要注意上面的代码如何说明逗号表达式在非声明符上下文中是如何良好的。
原因(为什么在数组声明符中需要括号)似乎是在 C 标准中,方括号中的数组大小是一个 赋值表达式,而不是 表达式(C17 草案,6.7.6.2 ¶3 和A.2.1);后者是逗号运算符的语法级别(C17 草案,A.2.1 (6.5.17)):
表情:
赋值表达式
表达式
赋值表达式,
如果扩展赋值表达式,最终会达到主表达式的级别(C17 草案,A.2.1 (6.5.1)):
主要表达:
标识符
恒定
字符串文字
表情(
)
通用选择
如果标准这么说,那就是这样,但是: 有语法上的必要性吗?也许有基于语言设计考虑的原因。 C 标准列出了以下 4 种形式的数组声明符(C17 草案,6.7.6.2 ¶3):
类型限定符列表opt 赋值表达式optD [
]
类型限定符列表opt 赋值表达式D [
]
类型限定符列表D [
赋值表达式static
]
类型限定符列表optD [
]
static
)。int arr[m, n]
时写下 int arr[m][n]
。顺便说一句,如果有人对为什么不能用 MSVC 编译有任何评论,我们也将不胜感激。
在数组声明语法规范中,长度是一个赋值表达式:
如果在声明“T D1”中,D1 具有以下形式之一:
D [ 类型限定符列表opt 赋值表达式opt ] 属性说明符序列opt
D [ 静态类型限定符列表opt 赋值表达式 ] 属性说明符序列opt
D [ 类型限定符列表 静态赋值表达式 ] 属性说明符序列opt
D [ 类型限定符列表opt * ] 属性说明符序列opt
并且在表达式语法规范中,赋值表达式不包括表达式,这是可以使用逗号运算符的地方。
因此,您必须将逗号表达式括在括号中,使其成为赋值表达式。