Search

8.13 — Struct initialization

In the previous lesson (8.12 -- Struct definition and member selection), we talked about how to define structs access their members. In this lesson, we’ll continue our exploration of structs, including how to initialize them, and how to pass them to functions.

Initializing structs

When a struct is defined, if no initializer is provided, each member of the struct is initialized identically to how it would be if it were defined outside the struct without an initializer. This means that members of a fundamental data type (e.g. int or double) will not be initialized by default.

For the same reason it’s a good idea to initialize your variables, it’s a good idea to initialize your structs.

When we initialize a normal variable, we provide a single initialization value. Because a struct can have multiple members, we need a way to initialize more than one value at initialization time. Because structs are an aggregate, they use a form of initialization called aggregate initialization. Aggregate initialization works just like normal initialization, but it allows you to initialize your aggregate using a list of values.

Structs can be copy-list or direct-list initialized:

Note that each of our initializers is a list of comma separated values!

Each of these initialization forms does a memberwise initialization, which means each member in the struct is initialized in the order of declaration. Thus, Employee joe { 2, 28, 45000.0 }; initializes joe’s id with value 2, joe’s age with value 28, and joe’s wage with value 45000.0.

Best practice

Prefer the braced list form of struct initialization.

If a struct is initialized but the number of initialization values is fewer than the number of members, then all remaining members will generally be zero-initialized.

For advanced readers

If the member is a class type with a default constructor, the member will instead be initialized to whatever default value the constructor function decides

This means we can use an empty list to initialize all member of the struct.

Const structs

Variables of a struct type can be const, and just like all const variables, they must be initialized.

Non-static member initialization

It’s also possible to give non-static struct members a default value. This is done by providing the default value in the struct definition:

Warning

In C++11, the non-static member initialization syntax is incompatible with list-initialization syntax. For example, in C++11, the following program won’t compile:

That makes non-static member initialization pretty useless in C++11. Fortunately, this limitation was fixed in C++14.

If both a non-static member initializer and a list-initializer are provided, the list-initializer takes precedence. In the above example, Rectangle x would be initialized with length and width 2.0.

Best practice

Default your non-static members to an appropriate value. That ensures that your struct members are initialized even if the struct variable definition doesn’t include initializers.

Key insight

Using default initializers (and other mechanisms that we’ll cover later), class types (which includes structs) can self-initialize to non-zero values.

Designated initializers

When initializing a struct from a list of values, the values in the list are applied to the members in order of declaration.

Now consider what would happen if you were to add a new member to your struct that is not the last member:

Now all your initialization values have shifted, and worse, the compile may not detect this as an error (after all, the syntax is still valid).

To help avoid this, C++20 adds a new way to initialize struct members called designated initializers. Designated initializers allow you to explicitly define which initialization values map to which members. The members must be initialized in the order in which they are declared in the struct, otherwise an error will result.

Now if you add a new member to the middle of the struct declaration, your initialization order will not match the order of declaration, and the compiler will error.

If there are less designated initializers than members, the remaining members are initialized in the same way as they would be for normal struct initialization.

Designated initializers are nice because they provide some level of self-documentation and help ensure you don’t inadvertently mix up the order of your initialization values.

List-assignment

As shown in the prior lesson, we can assign values to members of structs individually:

This can be a pain, particularly for structs with many members. Similar to initializing a struct with a list of values, you can also assign values to structs using a list of values:


8.14 -- Struct passing and miscellany
Index
8.12 -- Struct definition and member selection

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">