Jos*_*eld 29 c++ undefined-behavior language-lawyer c++11
我已经看到了其他类似的问题,并阅读了有关它的缺陷.但我仍然没有得到它.为什么i = ++i + 1
在C++ 11中定义得很好i = i++ + 1
?该标准如何明确定义?
通过我的工作,我在图之前有以下顺序(其中箭头表示关系之前的顺序,除非另有说明,否则一切都是值计算):
i = ++i + 1
^
|
assignment (side effect on i)
^ ^
| |
?i ++i + 1
|| ^
i+=1 |
^ 1
|
?assignment (side effect on i)
^ ^
| |
i 1
Run Code Online (Sandbox Code Playgroud)
我i
用黑星标记了一个副作用,i
用白星计算了一个值.这些似乎相互之间没有相应的顺序(根据我的逻辑).标准说:
如果对标量对象的副作用相对于同一标量对象的另一个副作用或使用相同标量对象的值进行的值计算未被排序,则行为未定义.
缺陷报告中的解释并没有帮助我理解.左值到右值的转换与任何事情有什么关系?我弄错了什么?
Joh*_*itb 22
...或使用相同标量对象的值计算值 ...
重要的部分是加粗的.左侧不使用i
值计算值.正在计算的是glvalue.仅在之后(之后排序),触摸并替换对象的值.
不幸的是,这是一个非常微妙的点:)
AnT*_*AnT 16
那么,关键时刻是结果++i
是左值.并且为了参与二进制+
,必须通过左值到右值的转换将左值转换为右值.Lvalue-to-rvalue转换基本上是i
从内存中读取变量的行为.
这意味着++i
应该获得的值就像直接从中读取一样i
.这意味着在概念上,新的(递增的)值i
必须在i
二进制+
开始评估之前准备好(必须物理存储).
这种额外的排序是无意中使得在这种情况下定义的行为.
在C++ 03中,没有严格要求++i
直接从中获取值i
.新值可以预测/预先拟定为i + 1
二进制的操作数,+
甚至在物理存储在实际存储之前i
.尽管可以合理地声称要求是隐含的,即使在C++ 03中(并且C++ 03不承认它的存在是C++ 03的缺陷)
如果是i++
,结果是右值.因为它已经是一个rvalue,所以没有涉及左值到右值的转换,并且i
在我们开始评估二进制文件之前绝对没有要求存储它+
.
归档时间: |
|
查看次数: |
2033 次 |
最近记录: |