I came across a strange bug today, which basically boils down to the following minimal example:
#include <cassert>
struct S* ps;
struct S{
S(){
ps = this;
}
//~S(){} //(*)
};
S makeS(){
return S{};
}
int main(){
S s{makeS()};
assert(&s == ps);
}
With guaranteed copy-elision, I believe that the assertion should never fail. However, when compiled with -std=c++20
in both gcc 13.1 and clang 16.0, the assertion would fail, as illustrated here. Increasing the optimization level does not help. If I uncomment the line marked (*)
and add a user-provided destructor, then the assertion no longer fails. Why is that?
NOTE: I am intentionally creating a duplicate question for Copy elision and trivially copyable types as a signpost (which is allowed according to meta) because I have spent very long time before I finally found the answer.