Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++11 value-initialization with defaulted default constructor

In the following example:

#include <iostream>

struct A {
    int z;
    A(std::string) {}
    A() = default;
};

int main() {
    char buf[1000];
    std::fill(buf, buf + 1000, 'x');
    auto a = new(buf) A{};
    std::cerr << "A.z: " << a->z << std::endl;
}

Compiled with GCC 4.8 outputs zero (same behavior with Clang 3.4). This seems to indicate that a is being zero-initialized before the default constructor is called.

But according to value-initialization rules on cppreference.com, the object should not be initialized before the default constructor invocation. Class A qualifies for bullet point #1 under C++11:

1) If T is a class type with at least one user-provided constructor of any kind, the default constructor is called.

Another perhaps useful data point is that if we replace A() = default with A() {} in the above example, no zero-initialization happens as expected. This seems to indicate that bullet point #2 of value initialization is being followed in the initial example which would be wrong:

2) If T is an non-union class type without any user-provided constructors, then the object is zero-initialized and then the implicitly-declared default constructor is called (unless it's trivial)

like image 965
mtoossi Avatar asked Jun 04 '14 17:06

mtoossi


People also ask

Can a constructor initialize variables to their defaults?

If you declare a static variable in a class, if you haven't initialized it, just like with instance variables compiler initializes these with default values in the default constructor. Yes, you can also initialize these values using the constructor.

Does default constructor zero initialize?

Implicitly defined (by the compiler) default constructor of a class does not initialize members of built-in types.

What is the default value initialized by the constructor for string type?

Most programmers use “” as the default value for String variables and 0 as the default value for int and double variables. If there are no constructors written for a class, Java provides a no-argument default constructor where the instance variables are set to their default values.


1 Answers

The wording that you cite for value initialization in C++11 was considered defective, see Core Working Group DR 1368 and the resolution in Core Working Group DR 1301 that changed the wording (showing additions with bold and deletions with strike through):

To value-initialize an object of type T means:

  • if T is a (possibly cv-qualified) class type (Clause 9 [class]) with either no default constructor (12.1 [class.ctor]) or a default constructor that is user-provided or deleted constructor (12.1 [class.ctor]), then the object is default-initialized default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);

  • if T is a (possibly cv-qualified) non-union class type without a user-provided or deleted default constructor, then the object is zero-initialized and, if T's implicitly-declared default constructor is T has a non-trivial default constructor, that constructor is called. default-initialized;

Some compilers - I believe GCC 4.8 and clang since 3.3ish - have already implemented the resolution of DR 1301.

like image 83
Casey Avatar answered Oct 19 '22 20:10

Casey