0

I’d like to know if there is some difference in specifying C++ default constructors for structs in situations in which default values are specified for some of the members:

struct Astruct {
    std::vector<double> v; /* has default constructor */
    double a;
    double b = 100.; /* has default value */
    Astruct() = default; /* default constructor */
};

and then initializing variables in different ways:

Astruct astruct = Astruct();
Astruct astruct{}; /* is it always the same as above? */
Astruct astruct = {}; /* shouldn't it force the default 'b' to zero? */
Astruct astruct; /* shouldn't it avoid any initialization at all? */

I see there’s many questions about default initializations from compiler-generated constructors, such as these:

Do the parentheses after the type name make a difference with new?

The new syntax "= default" in C++11

Difference between =default and empty constructor with no arguments?

What is instantiated when a POD structure is declared without using a default constructor?

But in all those questions, the structs declared all had POD types with no default values specified.

Now, I’ve played a bit with these initializers, and I see that e.g. in new Astruct (no parentheses at the end), b gets initialized to my provided default, but a doesn’t get initialized to zero - I wouldn't have expected the default value to still be there, and am wondering if that means introducing a default value somehow changed the way in which default-initialization works for POD members of the struct.

Nevertheless, the results I get vary with each run (sometimes a is also zero with new Astruct), so I’m not 100% confident that everything I am getting is due to the initializations being guaranteed as per the standard, or due to lucky runs in which memory is already zero-initialized or reused from before.

What is supposed to happen in these 4 ways of initializing astruct? Would there be any difference in terms of what any of those 4 lines does when declaring the constructor as Astruct() = default vs. Astruct() {}? Do default values somehow make a difference in terms of the default-initialization with such compiler-generated constructor?

anymous.asker
  • 1,179
  • 9
  • 14
  • I feel like you have too many questions in one. For example, the difference between defaulted constructor and empty constructor is subtle, but doesn't necessarily apply to the questions on member initialization, as they both would behave in a same way. – SergeyA Jul 15 '20 at 20:30
  • Thanks for the feedback, edited the question a bit. – anymous.asker Jul 15 '20 at 20:34
  • I'm reasonably sure that all four ways to initialize `astruct` you've shown do the same thing - run default constructor of `v`, set `b` to `100`, and leave `a` uninitialized (if it's occasionally zero, it's purely by accident). – Igor Tandetnik Jul 16 '20 at 01:54
  • @IgorTandetnik but this other answer suggests that the first one should initialize `a` to zero in C++03 and higher: https://stackoverflow.com/questions/620137/do-the-parentheses-after-the-type-name-make-a-difference-with-new – anymous.asker Jul 16 '20 at 05:16
  • 1
    Yes, I take it back. `Astruct()` does perform *value-initialization*, which zero-initializes all members (at which point `a = 0`), and then invokes the implicitly-defined default constructor that sets `b=100`. So does `Astruct astruct{}` and `Astruct astruct = {};`. In your example, only `Astruct astruct;` leaves `a` uninitialized. – Igor Tandetnik Jul 16 '20 at 14:07

0 Answers0