以下是未定义的行为吗? i = func(i)

时间:2017-02-03 09:51:36

标签: c++ undefined-behavior

我知道i=i++;是未定义的行为,因为i在序列点;之前更改了两次。

但我不知道编译器是否保证这种情况,如下所示不是未定义的行为:

int func(int &i)
{
    i++;
    return i;
}

int i = 1;
i = func(i);

1 个答案:

答案 0 :(得分:44)

首先,现代C ++已经从旧的(不充分的)概念转变为#34;序列点"对#34;排序"的新概念(即"在"之前排序;"在&#34之后排序;)。虽然i = i++仍然未定义,但i = ++i现在实际上是完美定义的。许多左值返回运算符中的排序规则被重新设计。

其次,您的版本在旧规范下以及在新规范下都是安全的。函数内部i的修改是安全的,孤立的"从作业转到i外面。在经典规范中,函数开头和结尾处的序列点安全地将i的修改(和读取)彼此分开。新的排序规则也保留了相同的保护级别。

说明函数调用提供的保护的示例可能如下所示

int inc(int &i) { return i++; }
...
int i = 1;

int r1 = i++ * i++ * i++;          
// Undefined behavior because of multiple unsequenced side effects
// applied to the same variable

int r2 = inc(i) * inc(i) + inc(i);
// No UB, but order of evaluation is unspecified. Since the result 
// depends on the order of evaluation, it is unspecified

int r3 = inc(i) + inc(i) + inc(i); 
// Perfectly defined result. Order of evaluation is still unspecified, 
// but the result does not depend on it