Is one side of an assignment sequenced before the other in c++?

浪子不回头ぞ 提交于 2019-12-21 11:03:13

问题


I understand that this is undefined behavior:

int i = 0;
int a[4];
a[i] = i++;  //<--- UB here

because the order of evaluation of i for the left hand side and the right hand side are undefined (the ; is the only sequence point).

Taking that reasoning a step further it seems to me that this would be undefined unspecified behavior:

int i = 0;

int foo(){
    return i++;
}

int main(){
    int a[4];
    a[i] = foo();
    return 0;
}

Even though there are a few sequence points on the right hand side of the = as far as I understand it is still undefined unspecified whether f() or a[i] is evaluated first.

Are my assumptions correct? Do I have to take painstaking care when I use a global or static variable on the left hand side of an assignment that the right hand does not under any circumstances modify it?


回答1:


a[i] = foo();

Here it is unspecified whether foo or a[i] is evaluted first. In the new C++11 wording, the two evaluations are unsequenced. That alone doesn't cause undefined behaviour, though. It is when there are two unsequenced accesses to the same scalar object, at least one of which is writing, where it does. That's why a[i] = i++; is UB.

The difference between these two statements is that a call to foo() does introduce a sequence point. C++11 wording is different: executions inside a called function are indeterminately sequenced with respect to other evaluations inside the calling function.

This means there's a partial ordering between a[i] and i++ inside foo. As a result, either a[0] or a[1] will get set to 0, but the program is well defined.




回答2:


a[i] = i++;

This is undefined behavior because the value of i is both modified and accessed between two sequence points (and the access is not directly involved in the computation of the next value of i). This is also unspecified behavior, because the order of evaulation is unspecified (the increment of i can happen before or after using i as the index into a).

When you introduce a function call, like :

a[i] = foo();

the function call introduces two further sequence points : one before the function is entered, and one after the function has returned.

This means that the increment of i inside the function is surrounded by two sequence points, and does not cause undefined behavior.

It is still unspecified behavior though whether the function call will be done before using i as an index on the left-hand side of the assignment, or after.



来源:https://stackoverflow.com/questions/22940686/is-one-side-of-an-assignment-sequenced-before-the-other-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!