Hi,
This is a gcc test case
extern “C” int printf (const char *, …);
int c;
int r;
struct A
{
A() { printf (“A()\n”); if (c++) r = 1; }
A(const A&) { printf (“A(const A&)\n”); ++c; }
~A() { printf (“~A()\n”); --c; }
};
struct B
{
B(int, const A& = A()) { printf (“B()\n”); }
};
int main()
{
B b[] = { 0, 1 };
return r;
}
Output from Clang (latest trunk):
A()
B()
A()
B()
~A()
~A()
Output from gcc 4.8 :
A()
B()
~A()
A()
B()
~A()
As we can see, the destructor of temporary objects are not called immediately in case of clang.
The temporary A passed to the constructor for b[0] should have been destroyed before going on to construct b[1].
According to standards,
The temporary to which the reference is bound or the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference except:
— A temporary bound to a reference member in a constructor’s ctor-initializer ( 12.6.2) persists until the constructor exits.
— A temporary bound to a reference parameter in a function call ( 5.2.2) persists until the completion of the full-expression containing the call.
So even though A’s temporary is bound to reference, it should get destroyed as soon as b[0] gets constructed before going forward to construct b[1].
This seems similar to http://llvm.org/bugs/show_bug.cgi?id=16476
Richard, any comment/help on this from you will be most welcomed (Since bug 16476 was filed by you :)). Does this require major change in code and handling of temporaries?
Is this also related to http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1634 ?