Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lifetime of temporary bound to aggregate initialized struct member

Given the following code:

class foo
{
};

class bar: public foo
{
public: 
    ~bar() { printf("~bar()\n"); }
};

class zab: public foo
{
public: 
    ~zab() { printf("~zab()\n"); }
};

struct foo_holder
{
    const foo &f;
};

int main()
{
    foo_holder holder[]= { {bar()}, {zab()} };
    printf("done!\n");
    return 0;
}

the output is:

~bar()
~zab()
done!

C++0x has a clause that dictates this can create dangling references when used as a new initializer, but it says nothing (at least nothing I can find) about aggregate initialization of const references with temporaries.

Is this unspecified behavior then?

like image 335
MSN Avatar asked Apr 19 '11 16:04

MSN


2 Answers

It isn't mentioned in the list of exceptions, therefore the lifetime to temporary should be extended to match lifetime of (array of) foo_holders. However, this looks like oversight to me, perhaps submitting Defect Report might be good idea.


§12.2/5 states, that when reference is bound to a temporary, the lifetime of temporary is extended to match lifetime of the reference and because const foo& f is member of foo_holder, the lifetime of the reference is matching lifetime of foo_holder, according to §3.7.5/1:

The storage duration of member subobjects, base class subobjects and array elements is that of their complete object (1.8).

This might be little bit tricky to interpret considering references, because §3.8/1 states, that lifetime of object ends when the storage is released or reused:

The lifetime of an object of type T ends when:

— if T is a class type with a non-trivial destructor (12.4), the destructor call starts, or

— the storage which the object occupies is reused or released.

however, it is left unspecified whether references use storage or not; §8.3.2/4 says

It is unspecified whether or not a reference requires storage (3.7).

Perhaps someone with better knowledge of standard would know this better.

like image 129
Vitus Avatar answered Oct 17 '22 12:10

Vitus


I got an answer on comp.std.c++:

http://groups.google.com/group/comp.std.c++/msg/9e779c0154d2f21b

Basically, the standard does not explicitly address it; therefore, it should behave the same as a reference declared locally.

like image 30
MSN Avatar answered Oct 17 '22 10:10

MSN