According to the accepted (and only) answer for this Stack Overflow question,
Defining the constructor with
MyTest() = default;
From cppreference:
Aggregate initialization initializes aggregates. It is a form of list-initialization.
An aggregate is one of the following types:
[snip]
class type [snip], that has
[snip] (there are variations for different standard versions)
no user-provided, inherited, or explicit constructors (explicitly defaulted or deleted constructors are allowed)
[snip] (there are more rules, which apply to both classes)
Given this definition, foo is an aggregate, while bar is not (it has user-provided, non-defaulted constructor).
Therefore for foo, T object {arg1, arg2, ...}; is syntax for aggregate initialisation.
The effects of aggregate initialization are:
[snip] (some details irrelevant to this case)
If the number of initializer clauses is less than the number of members or initializer list is completely empty, the remaining members are value-initialized.
Therefore a.a is value initialised, which for int means zero initialisation.
For bar, T object {}; on the other hand is value initialisation (of the class instance, not value initialisation of members!). Since it is a class type with a default constructor, the default constructor is called. The default constructor that you defined default initialises the members (by virtue of not having member initialisers), which in case of int (with non-static storage) leaves b.b with an indeterminate value.
And for pod-types, the default initialization is zero-initialization.
No. This is wrong.
P.S. A word about your experiment and your conclusion: Seeing that output is zero does not necessarily mean that the variable was zero initialised. Zero is perfectly possible number for a garbage value.
for that I ran the program maybe 5~6 times before posting and about 10 times now, a is always zero. b changes around a little.
The fact that the value was same multiple times does not necessarily mean that it was initialised either.
I also tried with set(CMAKE_CXX_STANDARD 14). The result was the same.
The fact that result is the same with multiple compiler options doesn't mean that the variable is initialised. (Although in some cases, changing standard version can change whether it is initialised).
How could I somehow shake my RAM a little so that if there was zero there, it should now be something else
There is no guaranteed way in C++ to make uninitialised value value to appear nonzero.
Only way to know that a variable is initialised is to compare program to the rules of the language and verify that the rules say that it is initialised. In this case a.a is indeed initialised.