考虑以下代码:
typedef vector<int> intVec;
intVec& operator<<(intVec& dst, const int i) {
dst.push_back(i);
return dst;
}
int intResult0() {
return 23;
}
int intResult1() {
return 42;
}
// main
intVec v;
v << intResult0() << intResult1();
奇怪的是,编译器生成代码,该代码计算intResult1
BEFORE intResult0
(使用最新的 VC 和 gcc 进行测试)。
编译器为什么要这样做?通过这样做,各个值的评估和使用之间的时间(不必要地)增加了(?),即首先获取 42,但最后推送到向量。
C++ 标准是否规定了这一点?
两个序列点之间的子表达式的求值顺序未定义。
上面的代码是语法糖:
v.operator<<(intResult0()).operator<<(intResult1());
编译器唯一的限制是它必须在调用方法之前评估所有参数并遵守优先级规则。但只要遵循这些规则,每个实现都可以选择细节,因此这个顺序可能会在编译器之间发生变化。
在这个例子中:
- 因此,在 intResult2() 之前调用 intResult1() 是完全合法的。
- 但必须在调用operator
- 并且必须在调用operator
- 并且operator
请参阅此处了解更多信息:
C++ 程序员应该了解哪些常见的未定义行为?
and
C++ 程序员应该了解哪些常见的未定义行为?
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)