I have a program that behaves differently in GCC and Clang. After simplification the minimal reproducible example is
struct A {
int i;
};
struct Finisher {
A & a;
~Finisher() { a.i = 1; }
};
A f() {
A a{0};
Finisher fr{a};
return a;
}
int main() {
std::cout << f().i;
}
In GCC it prints 0
and in Clang the output is 1
. Online demo: https://gcc.godbolt.org/z/oW4K93bM8
From the observed program behavior, it looks like Clang first performs ~Finisher()
, which sets a.i=1
, and only then return a
. And GCC seemingly chooses the opposite order of operations: first returns a.i=0
, and only then executes the destructor of fr
.
Is there any undefined behavior in the program? And is it possible to modify Finisher
in a way to always change the value of a
just before returning it from the function (to return 1
)?
A
that gets returned fromf
is initialized beforefr
is destroyed, so it'si
is0
. Clang appears to be doing NRVO anda
in the function is the sameA
object used instd::cout << f().i
and so you see1
asfr
is destroyed beforecout
prints. – Kingston