I'm trying to understand how the following construction behaves differently across C standards, and what the guarantees are on elements a
and b
.
struct X {
int a;
int b;
};
void func() {
X x(1); // (1) Works in c 2a only
X y{1}; // (2) Works in c 1z
X z(1); // (3) Does not work in all versions
}
CodePudding user response:
This has nothing to do with the default constructor being trivial, or really with the default constructor at all.
X y{1};
does aggregate-initialization which doesn't use any constructor, but instead initialized members of an aggregate (which your class is since it doesn't explicitly declare any constructors) directly one-by-one from the braced initializer list. The remaining members which are not explicitly given a value are value-initialized, which here means that b
will be zero-initialized.
X x(1);
can also initialize aggregates in the same way (with minor differences not relevant here) since C 20. Before that, non-empty parenthesized initializers would only try constructors. But there is no constructor that takes a single argument of type int
in your class. There is only an implicitly-declared default constructor which takes no arguments and implicitly-declared copy and move constructors, which take references to a X
as argument.