在c ++中,作业的一侧是在另一侧之前排序吗?

odi*_*erd 7 c++ sequence-points

我知道这是未定义的行为:

int i = 0;
int a[4];
a[i] = i++;  //<--- UB here
Run Code Online (Sandbox Code Playgroud)

因为i左手侧和右手侧的评估顺序是不确定的(这;是唯一的序列点).

把这个推理更进一步,在我看来,这将是 未定义 未指明的行为:

int i = 0;

int foo(){
    return i++;
}

int main(){
    int a[4];
    a[i] = foo();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

尽管在=我理解的情况下,在右侧有一些序列点仍然存在未定义未指定是否f()a[i]首先评估.

我的假设是否正确?当我在作业的左侧使用全局或静态变量时,我是否必须小心谨慎,右手在任何情况下都不会修改它?

jro*_*rok 6

a[i] = foo();
Run Code Online (Sandbox Code Playgroud)

这是不确定是否foo还是a[i]先evaluted.在新的C++ 11措辞中,这两个评估没有得到解释.但是,仅此一点不会导致未定义的行为.当对同一个标量对象进行两次未经测试的访问时,至少有一个是在写入的地方,它就是这样做的.这a[i] = i++;就是UB 的原因.

这两个语句之间的区别在于调用foo()确实引入了一个序列点.C++ 11的措辞是不同的:调用函数内的执行与调用函数内的其他评估不确定地排序.

这意味着在内部a[i]i++内部之间存在部分顺序foo.其结果是,无论是a[0]a[1]将设置为0,但该方案被明确定义.