Value Initialization in GCC

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

I believe I've found an instance where GCC (as of 7.1) does not
correspond to the standard (the output from Clang 4.0.0 does
correspond to the standard, at least as I understand it)

The code in question is:

#include <new>

struct A
{
    int x;
    int y;
    unsigned char data[1024];

    A() : x{ 1 } {}
};

struct B
{
    B() = default;

    A a;
};

template <typename T>
void default_initialize(unsigned char* storage)
{
    new ((void*)storage) T;
}

template <typename T>
void value_initialize(unsigned char* storage)
{
    new ((void*)storage) T();
}

template void default_initialize<A>(unsigned char*);
template void value_initialize<A>(unsigned char*);

template void default_initialize<B>(unsigned char*);
template void value_initialize<B>(unsigned char*);

My reading of the standard (N4296) inidcates that the call to
value_initialize<B> should zero the underlying memory (include data
from A). Clang does this, but GCC does not. Is this an intentional
choice to deviate from the standard for the sake of performance? (I
wasn't able to find any documentation indicating this).

Here are the relevant sections of the standard:

12.6.1
When no initializer is specified for an object of (possibly
cv-qualified) class type (or array thereof), or the initializer has
the form (), the object is initialized as specified in 8.5.

8.5.11
An object whose initializer is an empty set of parentheses, i.e., (),
shall be value-initialized.

8.5.12
If no initializer is specified for an object, the object is default-initialized.

8.5.8
To value-initialize an object of type T means:
(8.5.8.1) — if T is a (possibly cv-qualified) class type (Clause 9)
with either no default constructor (12.1) or a default constructor
that is user-provided or deleted, then the object is
default-initialized;
(8.5.8.2) — if T is a (possibly cv-qualified) class type without a
user-provided or deleted default constructor, then the object is
zero-initialized and the semantic constraints for
default-initialization are checked, and if T has a non-trivial default
constructor, the object is default-initialized;

8.5.6
To zero-initialize an object or reference of type T means:
(8.5.6.2) — if T is a (possibly cv-qualified) non-union class type,
each non-static data member and each base-class subobject is
zero-initialized and padding is initialized to zero bits;

8.5.7
To default-initialize an object of type T means:
(8.5.7.1) — If T is a (possibly cv-qualified) class type (Clause 9),
constructors are considered. The applicable constructors are
enumerated (13.3.1.3), and the best one for the initializer () is
chosen through overload resolution (13.3). The constructor thus
selected is called, with an empty argument list, to initialize the
object.

It seems that when new B(); is called, the object should be
value-initialized. Since B provides a defaulted (i.e.
non-user-provided default constructor, it should be zero-initialized
as in 8.5.8.2, but GCC 7.1 does not do this (see
https://godbolt.org/g/xf1kxk for reference).

Thanks,
Sam




[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux