c - 是否必须尽可能对三元运算符进行静态评估?

标签 c language-lawyer

是否要求尽可能对三元运算符进行静态评估,或者编译器是否可以将其推迟到以后,从而拒绝依赖于静态评估的程序?

更准确地说,这是一个程序的模棱两可的片段:

char b[sizeof(a) > 10 ? 10 : sizeof(a)] = {0};

根据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;
}
error: variable-sized object may not be initialized

但是如果 a 不是 VLA,那么一切都可以静态求值:

int main() {
  int a[42];
  char b[sizeof(a) > 10 ? 10 : sizeof(a)] = {0}; // valid
  return 0;
}

我的问题是:符合标准的编译器是否需要尽可能进行静态评估,因此必须接受第二个程序,或者他们是否允许“将其推迟到动态评估”并且可能拒绝它?

最佳答案

第二种情况:

int a[42];
char b[sizeof(a) > 10 ? 10 : sizeof(a)] = {0};

表达式 sizeof(a) > 10 ? 10 : sizeof(a) 被视为 常量表达式,如 C standard 的第 6.6 节中所定义, 也是一个整数常量表达式

从第 6.6p3 节开始,陈述了对常量表达式的约束:

Constant expressions shall not contain assignment, increment, decrement, function-call, or comma operators, except when they are contained within a subexpression that is not evaluated.

上述表达式不包含任何不允许的运算符。

第 6.6p6 节进一步详细介绍了整数常量表达式:

An integer constant expression 117) shall have integer type and shall only have operands that are integer constants, enumeration constants, character constants, sizeof expressions whose results are integer constants, _Alignof expressions, and floating constants that are the immediate operands of casts. Cast operators in an integer constant expression shall only convert arithmetic types to integer types, except as part of an operand to the sizeof or _Alignof operator .

和脚注 117:

117) An integer constant expression is required in a number of contexts such as the size of a bit-field member of a structure, the value of an enumeration constant, and the size of a non-variable length array. Further constraints that apply to the integer constant expressions used in conditional-inclusion preprocessing directives are discussed in 6.10.1

因为 a 不是可变长度数组,sizeof(a) 的计算结果为整数常量。并且因为 sizeof(a) > 10 ? 10 : sizeof(a) 仅包含 10 这是一个整数常量,sizeof(a) 计算结果为一个整数常量,以及运算符 ?:> 不是不允许的运算符,整个表达式被认为是一个整数常量表达式,可以作为一个不可变长度的大小数组,这意味着您可以对其进行初始化。

关于c - 是否必须尽可能对三元运算符进行静态评估?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56239713/

相关文章:

c++ - 可以使用 static_cast 破坏 protected 成员访问检查吗?

c++ - 来自 "The C++ Programming Language"第 4 版第 36.3.6 节的这段代码是否具有明确定义的行为?

c - snprintf 中的 strlen 调用是否导致此段错误?

c - 数组的最后一个元素不同的值

c++ - 不同编译器之间的名称查找不一致

c - & 后跟 * 运算符的行为

c++ - 为什么文字不是 const(字符串除外)?

c - 简单的套接字库需要一些检查

c - C 中的移位运算符(<<、>>)是算术运算符还是逻辑运算符?

从 R 调用 MPI 以运行 C 代码