我知道i=i++;
是未定义的行为,因为i
在序列点;
之前更改了两次。
但我不知道编译器是否保证这种情况,如下所示不是未定义的行为:
int func(int &i)
{
i++;
return i;
}
int i = 1;
i = func(i);
答案 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