[PATCH] 77864 Fix noexcept conditions for map/set default constructors

Jonathan Wakely jwakely@redhat.com
Sun Oct 9 15:14:00 GMT 2016

On 08/10/16 22:55 +0200, François Dumont wrote:
>On 06/10/2016 23:34, Jonathan Wakely wrote:
>>On 06/10/16 22:17 +0200, François Dumont wrote:
>>>Another approach is to rely on existing compiler ability to 
>>>compute conditional noexcept when defaulting implementations. This 
>>>is what I have done in this patch.
>>>The new default constructor on _Rb_tree_node_base is not a problem 
>>>as it is not used to build _Rb_tree_node.
>>Why not?
>_Rb_tree_node_base is used in 2 context. As member of _Rb_tree_impl in 
>which case we need the new default constructor. And also as base class 
>of _Rb_tree_node which is never constructed. Nodes are being allocated 
>and then associated value is being constructed through the allocator, 
>the node default constructor itself is never invoked.

In C++03 mode that is true, but it's only valid because the type is
trivially-constructible. If the type requires "non-vacuous
initialization" then it's not valid to allocate memory for it and
start using it without invoking a constructor. If you add a
non-trivial constructor then we can't do that any more.

In C++11 and later, see line 550 in <bits/stl_tree.h>

        ::new(__node) _Rb_tree_node<_Val>;

This default-constructs a tree node. Currently there is no
user-provided default constructor, so default-construction does no
initialization. Adding your constructor would mean it is used for
every node.

>    If you think it is cleaner to create an intermediate type that 
>will take care of this initialization through its default constructor 
>I can do that.
>>>I'll try to do the same for copy constructor/assignment and move 
>>We need to make sure we don't change whether any of those operations
>>are trivial (which shouldn't be a problem for copy/move, because they
>>are definitely very non-trivial and will stay that way!)
>>Does this change the default constructors from non-trivial to trivial?
>It would be a major compiler bug if making a constructor default was 
>making it trivial.

I must be misunderstanding you, because this is not a bug:

#include <type_traits>

struct A {
  A() { }

static_assert( !std::is_trivially_default_constructible<A>::value, "" );

struct B {
  B() = default;

static_assert( std::is_trivially_default_constructible<B>::value, "" );

More information about the Gcc-patches mailing list