Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

struct - C++ zero initialization without constructor

I don't understand what happens regarding the zero initialization of structs that has default values for its members.

If I have these structs:

struct A {
  int *a;
  int b;
};

struct B {
  int *a;
  int b;
  B() : b(3) {}
};

struct C {
  int *a;
  int b = 3;
};

What we can say without a doubt is:

  • A a; leaves all fields uninitialized
  • A a{}; is {nullptr, 0}
  • B b; and B b{}; both are {garbage, 3} (the constructor is called)

Now it's unclear what happens when I do the following, here are the results using gcc:

C c; // {garbage, 3}
C c{}; // {nullptr, 3}

The question is: does C c{}; guarantees that C::a is initialized to nullptr, in other words, does having default members like in C still zero initialize the other members if I explicitly construct the object like C c{};?

Because it's not what happens if I have a constructor that does the same thing than C (like in B), the other members are not zero initialized, but why? What is the difference between B and C?

question from:https://stackoverflow.com/questions/65886215/c-zero-initialization-without-constructor

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As of C++14, C is an aggregate (like A), and C c{} syntax performs aggregate initialization. This includes, in part:

[dcl.init.aggr]/8 If there are fewer initializer-clauses in the list than there are elements in a non-union aggregate, then each element not explicitly initialized is initialized as follows:
(8.1) — If the element has a default member initializer (12.2), the element is initialized from that initializer.
(8.2) — Otherwise, if the element is not a reference, the element is copy-initialized from an empty initializer list (11.6.4).
(8.3) — Otherwise, the program is ill-formed.

So C c{}; is equivalent to C c{{}, 3};. Initializing an int* member with empty list causes it to be zero-initialized.

In C++11, C is not an aggregate (having a default member initializer was disqualifying), and C c{}; calls an implicitly-defined constructor that leaves c.a member uninitialized.

In all versions of the standard, B is not an aggregate due to the user-defined constructor. B b{}; calls that constructor, which explicitly initializes b member and chooses to leave a uninitialized.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...