是否需要在可能的情况下对三元运算符进行静态评估,还是编译器可以将其推迟到以后使用,从而拒绝依赖于其静态评估的程序?
更准确地说,这是程序的歧义片段:
char b[sizeof(a) > 10 ? 10 : sizeof(a)] = {0};
Run Code Online (Sandbox Code Playgroud)
取决于a片段是否为可变长度,片段是否无效。如果a是VLA,则sizeof(a)不是静态确定的,因此无法进行初始化:
int main(int argc, char **argv) {
int a[argc];
char b[sizeof(a) > 10 ? 10 : sizeof(a)] = {0}; // invalid
return 0;
}
Run Code Online (Sandbox Code Playgroud)
error: variable-sized object may not be initialized
Run Code Online (Sandbox Code Playgroud)
但是,如果a不是VLA,则可以静态评估所有内容:
int main() {
int a[42];
char b[sizeof(a) > 10 ? 10 : sizeof(a)] = {0}; // valid
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:符合标准的编译器所需的静态尽可能评估,因此必须接受第二个方案,或者允许他们“它推迟到动态评价”,并可能拒绝呢?
在第二种情况下:
int a[42];
char b[sizeof(a) > 10 ? 10 : sizeof(a)] = {0};
Run Code Online (Sandbox Code Playgroud)
该表达式sizeof(a) > 10 ? 10 : sizeof(a)被视为C标准 6.6节中定义的常量表达式,并且它也是整数常量表达式。
从6.6p3节开始,陈述了对一个常量表达式的约束:
常量表达式不得包含赋值,递增,递减,函数调用或逗号运算符,除非它们包含在未求值的子表达式中。
上面的表达式不包含任何不允许的运算符。
6.6p6节进一步详细说明了整数常量表达式:
的整数常量表达式117)应具有整数型和应仅具有是操作数 的整数常数,枚举常数,字符常数,
sizeof表达式,其结果是积分常数,_Alignof表达式和浮动是铸件的立即操作数的常量。整数常量表达式中的强制转换运算符只能将算术类型转换为整数类型,除非作为sizeofor_Alignof运算符的操作数的一部分。
脚注117:
117)在许多情况下都需要整数常量表达式,例如结构的位字段成员的大小,枚举常量的值 以及非可变长度数组的大小。 6.10.1中讨论了适用于条件包含预处理指令中的整数常量表达式的其他约束。
因为a不是可变长度数组,所以sizeof(a)求值为整数常量。并且由于sizeof(a) > 10 ? 10 : sizeof(a)只包含10一个整数常量( sizeof(a)其结果为整数常量)以及该运算符?:和>不允许使用的运算符,因此整个表达式被视为整数常量表达式,可以用作非可变长度数组的大小,表示您可以对其进行初始化。