[cfe-commits] r148348 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Sema/Sema.cpp lib/Sema/SemaDeclCXX.cpp

Eli Friedman eli.friedman at gmail.com
Wed Jan 18 03:09:15 PST 2012


On Wed, Jan 18, 2012 at 3:01 AM, Eli Friedman <eli.friedman at gmail.com> wrote:
> On Tue, Jan 17, 2012 at 4:31 PM, Sebastian Redl
> <sebastian.redl at getdesigned.at> wrote:
>> Also, I believe the specification of the lifetime of the backing array to be highly defective. [dcl.init.list] says:
>> "Otherwise, if T is a specialization of std::initializer_list<E>, an initializer_list object is constructed as described below and used to initialize the object according to the rules for initialization of an object from a class of the same type."
>> Note that it says that an object is constructed and then basically copied to the actual object. Below, it says:
>> "The lifetime of the array is the same as that of the initializer_list object."
>> So if a temporary is constructed, wouldn't the lifetime of the array be that of the temporary?
>> The example contradicts this, of course, since that would be stupid, but if the lifetime of the array is the same as that of the actual initializer_list object, then how do you implement this?
>
> I agree; I don't see how the example can possibly work without either
> some std::initializer_list-specific magic in the compiler or a library
> implementation of std::initializer_list that looks nothing like the
> one currently in libc++.  (I think the compiler could actually follow
> the standard if std::initializer_list had an appropriate move
> constructor and destructor which destroyed the elements, and the
> associated memory somehow had block-scope lifetime.)
>
>> auto listptr = new std::initializer_list<int>{1, 2, 3, 4, 5};
>>
>> Or for that matter, since it's equivalent:
>> auto listptr = new auto{1, 2, 3, 4, 5};
>
> "warning: allocating an std::initializer_list with new likely leads to
> undefined behavior.  The simplest way to get the behavior you clearly
> want with the C++ standard library is 'auto listptr = new
> std::array<int,5>{{1,2,3,4,5}}'."
>
> Or we could special-case this somehow to actually request the right
> amount of memory from operator new, but that seems to be way outside
> anything the standard suggests we can or should do.

Actually, thinking about it a bit more, we could easily stop people
from accidentally writing anything that leads to undefined behavior by
making std::initializer_list's destructor private.  I wonder why it
wasn't specified that way.

-Eli




More information about the cfe-commits mailing list