考虑以下表达式中的序列点
i = (++i,i++,i);
如果我是正确的,执行步骤如下:
1)
++i, i++
2)
step1,i
3)
i = step2
对于步骤 1 中的评估,i 的值应该只修改一次,以便将构造称为定义(因为在评估逗号运算符之后有一个序列点)。但我认为情况并非如此。因此它应该是未定义的。请看这个答案。这里上述表达式被称为定义。我错过了什么吗?
考虑以下表达式中的序列点
i = (++i,i++,i);
如果我是正确的,执行步骤如下:
1)
++i, i++
2)
step1,i
3)
i = step2
对于步骤 1 中的评估,i 的值应该只修改一次,以便将构造称为定义(因为在评估逗号运算符之后有一个序列点)。但我认为情况并非如此。因此它应该是未定义的。请看这个答案。这里上述表达式被称为定义。我错过了什么吗?
以下指令的行为是明确定义的。
i = (++i, i++, i);
,
在逗号运算符 ( )的第一个和第二个操作数的计算之间确实存在一个序列点。标准的附录 C 虽然提供了信息,但提供了对序列点的描述。
C11,附件 C 序列点
以下是5.1.2.3中描述的顺序点:
— 在函数调用和实际调用中函数指示符和实际参数的评估之间。(6.5.2.2)。
— 在以下运算符的第一个和第二个操作数的计算之间:逻辑 AND && (6.5.13);逻辑或 || (6.5.14);逗号 , (6.5.17)。
— 在条件的第一个操作数的评估之间?: 运算符以及计算第二个和第三个操作数中的任何一个(6.5.15)。— 完整声明符的结尾:声明符(6.7.6);
— 在完整表达式的计算和要计算的下一个完整表达式之间。以下是完整的表达式: 不属于复合文字(6.7.9)的初始化器;表达式语句中的表达式 (6.8.3);选择语句(if 或 switch)的控制表达式(6.8.4);while 或 do 语句的控制表达式 (6.8.5);for 语句 (6.8.5.3) 的每个(可选)表达式;return 语句 (6.8.6.4) 中的(可选)表达式。
— 紧接在库函数返回之前 (7.1.4)。— 在与每个格式化输入/输出函数转换说明符(7.21.6、7.29.2)相关的动作之后。
— 在每次调用比较函数之前和之后,以及在对比较函数的任何调用与作为参数传递给该调用的对象的任何移动之间(7.22.5)。