在以下代码中调用f(a,a)
是未定义的行为吗?
#include <iostream>
int f(int &m, int &n) {
m++;
n++;
return m + n;
}
int main() {
int a = 1;
int b = f(a, a);
}
答案 0 :(得分:3)
修改m
和n
没有undefined behavior,因为两个变量的修改都是按顺序排列的。 m
的修改将在修改n
之前发生,因为它们都是完整表达式,并且在下一个完整表达式的副作用之前对完整表达式的所有副作用进行排序。
draft C++ standard的相关部分是1.9
部分执行部分,其中包含:
与a相关的每个值计算和副作用 full-expression在每个值计算和side之前排序 与要评估的下一个完整表达相关联的效果.8。
和
如果标量对象的副作用相对于其中任何一个都没有排序 对同一标量对象或值计算的另一个副作用 使用相同标量对象的值,行为未定义
另一方面如下:
m++ + n++ ;
是未定义的行为,因为每个子表达式的评估顺序是相对于彼此不确定的顺序。
Jonathan提出strict aliasing的问题,但我不知道编译器如何假设n
和m
没有相互混淆我的实验godbolt 3}}并不表示任何意外的别名假设。
注意,完整表达式是:
[...]表达式不是另一个表达式[...]
的子表达式
通常;
表示完整表达式的结尾。
答案 1 :(得分:1)
这里没有未定义的行为。 a
最终将3
b
6
一致。