C++ function evaluation order in assignment operat

2020-02-11 03:32发布

问题:

int& foo() {
   printf("Foo\n");
   static int a;
   return a;
}

int bar() {
   printf("Bar\n");
   return 1;
}

void main() {
   foo() = bar();
}

I am not sure which one should be evaluated first.

I have tried in VC that bar function is executed first. However, in compiler by g++ (FreeBSD), it gives out foo function evaluated first.

Much interesting question is derived from the above problem, suppose I have a dynamic array (std::vector)

std::vector<int> vec;

int foobar() {
   vec.resize( vec.size() + 1 );
   return vec.size();
}

void main() {
   vec.resize( 2 );
   vec[0] = foobar();
}

Based on previous result, the vc evaluates the foobar() and then perform the vector operator[]. It is no problem in such case. However, for gcc, since the vec[0] is being evaluated and foobar() function may lead to change the internal pointer of array. The vec[0] can be invalidated after executation of foobar().

Is it meant that we need to separate the code such that

void main() {
   vec.resize( 2 );
   int a = foobar();
   vec[0] = a;
}

回答1:

Order of evaluation would be unspecified in that case. Dont write such code

Similar example here



回答2:

The concept in C++ that governs whether the order of evaluation is defined is called the sequence point.

Basically, at a sequence point, it is guaranteed that all expressions prior to that point (with observable side effects) have been evaluated, and that no expressions beyond that point have been evaluated yet.

Though some might find it surprising, the assignment operator is not a sequence point. A full list of all sequence points is in the Wikipedia article.



回答3:

Order of evaluation of an expression is Unspecified Behaviour.
It depends on the compiler which order it chooses to evaluate.

You should refrain from writing shuch codes.
Though if there is no side effect then the order shouldn't matter.

If the order matters, then your code is wrong/ Not portable/ may give different result accross different compilers**.