对于调用结果的复制初始化顺序,它是否被认为是 GCC 和 Clang 的错误?

Is it considered the bug of both GCC and Clang for the sequence of copy-initialization of the result of a call?

请看这个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();
}

以上示例的输出在 GCC 和 Clang 中都是相同的,它们是

A constructed
C constructed
B constructed
B destroyed
C destroyed
A destroyed
D constructed

这意味着调用结果的复制初始化在该函数的局部或临时变量的所有销毁之后排序。它与以下规则相矛盾,即
[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.

根据规则,输出应该是

A constructed
C constructed
B constructed
D constructed
B destroyed
C destroyed
A destroyed

是不是GCC和Clang的bug?

相关函数的 return 值为 bool。这就是 returned.

您的记录输出没有显示 bool return 值的复制初始化何时排序的证据,在其他任何事情之前或之后。

一旦 bool 值被 returned,调用者就用它来构造一个新的 D 实例。但这与函数调用中 returned bool 值的复制初始化语义完全无关。