C++ 在c+中,赋值的一方在另一方之前排序+;?

C++ 在c+中,赋值的一方在另一方之前排序+;?,c++,sequence-points,C++,Sequence Points,我理解这是未定义的行为: int i = 0; int a[4]; a[i] = i++; //<--- UB here int i = 0; int foo(){ return i++; } int main(){ int a[4]; a[i] = foo(); return 0; } 尽管在=的右侧有几个序列点,但据我所知,仍然没有定义是先计算f()还是a[I] 我的假设正确吗?当我在赋值的左侧使用全局变量或静态变量,而右侧在任何情况下都不会对

我理解这是未定义的行为:

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

int foo(){
    return i++;
}

int main(){
    int a[4];
    a[i] = foo();
    return 0;
}
尽管在
=
的右侧有几个序列点,但据我所知,仍然没有定义是先计算
f()
还是
a[I]

我的假设正确吗?当我在赋值的左侧使用全局变量或静态变量,而右侧在任何情况下都不会对其进行修改时,我是否必须非常小心

a[i] = i++;
这是未定义的行为,因为
i
的值是在两个序列点之间修改和访问的(并且访问不直接涉及
i
的下一个值的计算)。 这也是未指定的行为,因为计算顺序未指定(使用
i
作为
a
的索引之前或之后,
i
的增量可能发生)

引入函数调用时,如:

a[i] = foo();
函数调用引入了另外两个序列点:一个在函数输入之前,另一个在函数返回之后

这意味着函数中
i
的增量被两个序列点包围,并且不会导致未定义的行为

尽管函数调用是在将
i
用作赋值左侧的索引之前还是之后进行,但这仍然是未指定的行为

a[i] = foo();
这里未说明是先计算
foo
还是
a[i]
。在新的C++11语言中,这两个求值是不连续的。不过,这本身并不会导致未定义的行为。当对同一标量对象有两个未排序的访问,其中至少有一个正在写入时,就会发生这种情况。这就是为什么
a[i]=i++是UB

这两个语句之间的区别在于对
foo()
的调用引入了一个序列点。C++11的措辞是不同的:被调用函数内的执行相对于调用函数内的其他求值是不确定顺序的


这意味着
a[i]
i++
内部
foo
之间存在偏序。因此,
a[0]
a[1]
将设置为0,但程序定义良好。

计算顺序未指定,而不是未定义。函数中的排序仅针对函数。还没有定义哪一个将首先发生,对
a
的解引用或函数调用。@chris谢谢你的更正,我的修复是否正确?i、 第一个是未定义的,第二个是未指定的吗?@PorkyBrain,在第一个片段下面仍然有一个,但我同意jrok的答案。您不知道它得到了什么值,但它将有两个可能的值之一。