Containers default initialization

François Dumont frs.dumont@gmail.com
Wed Jun 7 20:44:00 GMT 2017


On 05/06/2017 13:31, Jonathan Wakely wrote:
> On 04/06/17 22:26 +0200, François Dumont wrote:
>> Hi
>>
>>    I have eventually adapt the test to all containers and the result 
>> is successful for map/set/unordered_map/unordered_set. It is failing 
>> for deque/list/forward_list/vector/vector<bool>.
>>
>>    I even try to change the test to look at the difference between an 
>> explicit call to the default constructor done through the placement 
>> new call and an implicit call done on normal declaration. I wondered 
>> if we would have the same kind of difference we have between a int i; 
>> and a int i(); I tried to set the stack to ~0 before declaring the 
>> instance. I know there is no guarantee on the content of the stack 
>> for the following declaration but do you think it is reliable enough 
>> to commit it ?
>>
>>    Ok to commit the successful tests ?
>
>
> No, I'm seeing failures for some of these if I add
> // { dg-options "-O0" }
>
>>    Franckly I don't understand the result of those tests. I would 
>> have expect map/set to fail and others to succeed. We might need help 
>> from compiler guys, no ?
>
> I think your tests are just insufficient. With optimisation enabled
> (the testsuite uses -O2 by default) the compiler can remove the memset
> just before the __aligned_buffer goes out of scope, because it is
> unobservable in a correct program. This is similar to the situation
> described at https://gcc.gnu.org/gcc-6/porting_to.html#flifetime-dse
>
> If I change the placement new-expressions to use default-init instead
> of value-init and use -O0 then I see all four tests FAIL here:
>
> test_type *tmp = ::new(buf._M_addr()) test_type; // not test_type()

Ok, I didn't know we could do this.

So I have added value_init.cc tests showing the problem for all containers.

The patch also contains the fix for rb_tree so that map/set are now 
successful.

Looks there is really a misunderstanding on what the compiler is doing. 
If container calls _Node_allocator() it will be transform by compiler 
into default initialization if container default container is being 
called or into value init if container is value initialized which takes 
place only if I call this:

test_type *tmp = ::new(buf._M_addr()) test_type {};

To force default/value init looks like gcc forces you to explicitly 
build an allocator instance like in the attached patch.

François

-------------- next part --------------
A non-text attachment was scrubbed...
Name: rb_tree.patch
Type: text/x-patch
Size: 12692 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/libstdc++/attachments/20170607/ec77df20/attachment.bin>


More information about the Libstdc++ mailing list