C逗号运算符

Gan*_*ian 15 c expression scope comma-operator

为什么在逗号运算符(例如下面的示例)中指定的表达式不被视为常量表达式?

例如,

int a = (10,20) ;
Run Code Online (Sandbox Code Playgroud)

当在全局范围内给出时产生错误"初始化器不是常量",尽管由逗号运算符分隔的两个表达式都是常量(常量表达式).为什么整个表达式不被视为常量表达式?为了澄清我已经阅读了','运算符在C中做了什么?C逗号运算符的使用.他们没有涉及逗号运算符的这个方面.

pax*_*blo 33

6.6/3,"常量表达式",在ISO C99标准的是你需要的部分.它指出:

常量表达式不应包含赋值,递增,递减,函数调用或逗号运算符,除非它们包含在未评估的子表达式中.

在ISO的C99基本原理文档中,有一个小片段:

整数常量表达式必须只涉及在转换时可知的数字,以及没有副作用的运算符.

而且,因为有一个在使用逗号操作毫无意义可言,如果你不依赖的副作用,它是在一个常量表达式没用.

通过这个,我的意思是两个代码段之间绝对没有区别:

while (10, 1) { ... }
while     (1) { ... }
Run Code Online (Sandbox Code Playgroud)

因为10实际上并没有任何事情.事实上,

10;
Run Code Online (Sandbox Code Playgroud)

这是一个完全有效的,但不是很有用的C语句,大多数人都不理解,直到他们更好地了解语言.

然而,就是这两个语句之间的区别:

while (  10, 1) { ... }
while (x=10, 1) { ... }
Run Code Online (Sandbox Code Playgroud)

后者使用逗号运算符会产生副作用,即将变量设置x10.

至于为什么他们不喜欢常量表达式中的副作用,常量表达式的全部意义在于它们可以在编译时进行求值而无需执行环境 - ISO对转换(编译时)和执行进行区分(运行时)环境.

关于为什么ISO决定要求编译器提供执行环境信息(除了包含在头文件中的东西之外)的原因的线索limits.h可以在理论文档中稍后找到:

然而,虽然实现当然允许在转换和执行环境中产生完全相同的结果,但要求这被认为是许多交叉编译器的不可容忍的负担.

换句话说,ISO不希望交叉编译器的制造商承担为每个可能的目标承载执行环境的负担.

  • +1:我只是在寻找这个.我认为更深入的原因是逗号运算符引入了一个序列点. (5认同)

CB *_*ley 6

ISO/IEC 9899:1999 6.6/3(常量表达式)规定,不同的表达式不应包含逗号运算符(除非是未计算的子表达式的一部分),因此(10,20)根据定义,它不是常量表达式.

基本原理必须是因为逗号表达式的第一部分的值不是使用它只有它的副作用,并且常量表达式没有副作用.