int& foo() {
printf("Foo\n");
static int a;
return a;
}
int bar() {
printf("Bar\n");
return 1;
}
void main() {
foo() = bar();
}
我不确定应该首先评估哪一个。
我在VC中尝试过先执行bar函数。但是,在g ++编译器(FreeBSD)中,它首先给出了foo函数的评估。
从上面的问题中得出很多有趣的问题,假设我有一个动态数组(std :: vector)
std::vector<int> vec;
int foobar() {
vec.resize( vec.size() + 1 );
return vec.size();
}
void main() {
vec.resize( 2 );
vec[0] = foobar();
}
根据以前的结果,vc计算foobar(),然后执行向量运算符[]。在这种情况下没有问题。但是,对于gcc,由于正在评估vec [0]并且foobar()函数可能导致更改数组的内部指针。执行foobar()后,vec [0]可以无效。
这是否意味着我们需要将代码分开,以便
void main() {
vec.resize( 2 );
int a = foobar();
vec[0] = a;
}
答案 0 :(得分:8)
在这种情况下,未指定评估顺序。不要写这样的代码
类似示例here
答案 1 :(得分:5)
C ++中用于控制评估顺序是否已定义的概念称为sequence point。
基本上,在序列点,可以保证在该点之前的所有表达式(具有可观察的副作用)已被评估,并且尚未评估超出该点的表达式。
虽然有些人可能会发现它令人惊讶,但赋值运算符不是序列点。所有序列点的完整列表位于Wikipedia article。
答案 2 :(得分:0)
表达式的评估顺序为未指定行为 这取决于编译器选择评估的顺序。
你应该避免写这些代码 虽然没有副作用,但顺序无关紧要。
如果订单很重要,那么您的代码错误 / 不便携 / 可能会在不同的编译器中提供不同的结果 **。