【发布时间】:2021-04-21 06:14:09
【问题描述】:
我正在查看 C17 的最终草案,N2176。在这里,我关心的是什么样的带有副作用的表达式会导致其行为未定义。
在标准的第 6.5 节表达式中,有第 2 段以:
如果标量对象的副作用相对于其中任一对象而言是未排序的 对同一标量对象或值的不同副作用 使用相同标量对象的值进行计算,行为是 未定义。
据我了解,表达式 x=1 的求值既会产生一个值,也会引发一个副作用,从而改变由 x 指定的对象的值。决定因素将是副作用是否以任何方式与使用 x 指定的对象的值的值计算相关。
6.5.16 赋值运算符中的描述包含这句话:
更新左操作数的存储值的副作用是 在左右操作数的值计算之后排序。
这不能解决整个赋值的值计算顺序和赋值的副作用。
还有一句话:
赋值表达式在 赋值,但不是左值。
指定最终值应该是什么,但不要求任何排序。而且我没有看到任何其他文字提到有关副作用和价值的排序。
我知道当写成完整的语句时 x=1;不使用赋值的值。但是,标准说该值被丢弃。这意味着好像首先对值进行评估然后丢弃,因此仍应触发未定义的行为。
标准中是否有任何其他部分使该语句行为未定义?
【问题讨论】:
-
你在部分引用的段落中的最后一句是“更新左操作数的存储值的副作用是在左操作数和右操作数的值计算之后排序的。评估的操作数是未排序的。" - 修改最后排序。
-
@StoryTeller-UnslanderMonica:这个问题没有询问副作用相对于操作数的值计算的顺序。它询问相对于赋值表达式的值计算的副作用的顺序。例如,考虑
y = (x = 1),由于副作用,它既修改了x,又“使用”x分配给y。 -
@EricPostpischil - 但它不会“使用”
x分配给y。它“使用”表达式(x = 1)。 -
@StoryTeller-UnslanderMonica:因此我的 this-is-not-really-what-it-means-quote-marks 和我的答案。虽然标准中的一个脚注说实现实际上可以读取
x来获取值!
标签: c language-lawyer c17