赋值运算符中的C ++函数求值顺序

时间:2011-11-28 11:33:21

标签: c++ function evaluation

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;
}

3 个答案:

答案 0 :(得分:8)

在这种情况下,未指定评估顺序。不要写这样的代码

类似示例here

答案 1 :(得分:5)

C ++中用于控制评估顺序是否已定义的概念称为sequence point

基本上,在序列点,可以保证在该点之前的所有表达式(具有可观察的副作用)已被评估,并且尚未评估超出该点的表达式。

虽然有些人可能会发现它令人惊讶,但赋值运算符不是序列点。所有序列点的完整列表位于Wikipedia article

答案 2 :(得分:0)

表达式的评估顺序为未指定行为 这取决于编译器选择评估的顺序。

你应该避免写这些代码 虽然没有副作用,但顺序无关紧要。

如果订单很重要,那么您的代码错误 / 不便携 / 可能会在不同的编译器中提供不同的结果 **。