Reputation: 7369
Please see this example
#include <iostream>
struct A{
A(){
std::cout<<"A constructed\n";
}
~A(){
std::cout<<"A destroyed\n";
}
};
struct B{
B(int){
std::cout<<"B constructed\n";
}
~B(){
std::cout<<"B destroyed\n";
}
};
struct C{
C(){
std::cout<<"C constructed\n";
}
~C(){
std::cout<<"C destroyed\n";
}
bool operator==(B const&){
return true;
}
};
struct D{
D(bool){
std::cout<<"D constructed\n";
}
};
bool fun(){
A a;
C c;
return c==0;
}
int main(){
D d = fun();
}
The outputs of the above example are identity in both GCC and Clang, they are that
A constructed
C constructed
B constructed
B destroyed
C destroyed
A destroyed
D constructed
That means the copy-initialization of the result of the call is sequenced after all the destruction of the local or temporary variable of that function. It contradicts with the following rule, which is
[stmt.return#3]
The copy-initialization of the result of the call is sequenced before the destruction of temporaries at the end of the full-expression established by the operand of the return statement, which, in turn, is sequenced before the destruction of local variables ([stmt.jump]) of the block enclosing the return statement.
According to the rule, the output should be that
A constructed
C constructed
B constructed
D constructed
B destroyed
C destroyed
A destroyed
Is it a bug of GCC and Clang?
Upvotes: 3
Views: 99
Reputation: 118445
The return value from the function in question is a bool
. This is what gets returned.
Your logged output shows no evidence of when the copy-initialization of the bool
return value was sequenced, before or after anything else.
It also happens to be true that once the bool
value is returned, the caller uses it to construct a new instance of D
. But this is something completely unrelated to the copy-initialization semantics of the returned bool
value from the function call.
Upvotes: 5