简体   繁体   中英

Execution order in GCC statement expressions

I found that there is a different execution order between two similar statements(the only difference is the below one has an additional ; ). The destructor order is different. Does C++ have a corresponding specification about that or it's only an unspecified behavior?

Environment: GCC10

#include <iostream>

template <int num>
struct S {
  S() {std::cout << "S(" << num << ")\n"; }
  ~S() {std::cout << "~S(" << num << ")\n"; }
};

int main() {
  ({S<1>(), S<2>();});
  std::cout << "-----------------------------------\n";
  ({S<3>(), S<4>();;});
}

output:

S(1)
S(2)
~S(1)
~S(2)
-----------------------------------
S(3)
S(4)
~S(4)
~S(3)

This is not standard C++. This is a GCC extension known as statement expression . A compound statement enclosed in parentheses can appear where an expression is allowed. If the last statement in the brace-enclosed block is an expression statement, then the value of this expression is also the value of the overall statement expression; otherwise, the statement expression is of type void and has no value.

Your first example is roughly equivalent to

([](){ return S<1>(), S<2>(); })();

(that's a lambda that's created and then called immediately). There's a comma expression that creates S<1> and S<2> temporaries. S<1> is destroyed, S<2> is, technically, copied to the return value - but that copy is elided. If it weren't for this copy elision, you'd see

S<1>()
S<2>()
S<2>(S<2>&&)  // (1) move constructor
~S<2>()  // (2) the original temporary is destroyed
~S<1>()
~S<2>()  // the copy is destroyed outside of the lambda

But the pair (1)/(2) is elided, leaving the sequence you observe in your example.

In the second example, the last statement within the braces is not an expression, so the whole thing doesn't have a value either. It's roughly equivalent to

([](){ S<3>(), S<4>(); return; })();

Both temporaries are created and destroyed within the lambda, and the usual rules apply - temporaries are destroyed in the reverse order of construction.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM