I had the following code:
#include <iostream>
struct T
{
int a, b, c;
};
int main()
{
T t = {0};
std::cout << t.a << ',' << t.b << ',' << t.c << '\n';
}
Output:
0,0,0
After many years of this code running happily in a critical production environment, serving a vital function, the requirements of the project changed and I needed the output to be 1,1,1
.
So, I changed {0}
to {1}
:
#include <iostream>
struct T
{
int a, b, c;
};
int main()
{
T t = {1};
std::cout << t.a << ',' << t.b << ',' << t.c << '\n';
}
Output:
1,0,0
I expected 1,1,1
instead.
Why are my struct
's members not all being initialised properly?
The direct answer is because the structure definition declares a type and not a variable that can be initialized. Your example is: struct s { int i=10; }; This does not declare any variable - it defines a type.
Structure members cannot be initialized with declaration.
A non POD struct may as well have a constructor so it can initialize members. If your struct is a POD then you can use an initializer. Alternatively you can use the default constructor. C c = C(); // Zero initialize using default constructor C c{}; // Latest versions accept this syntax.
// In C++ We can Initialize the Variables with Declaration in Structure. Structure members can be initialized using curly braces '{}'. For example, following is a valid initialization.
When you write = {0}
, that only explicitly initialises the first member; the rest are zero-initialised implicitly according to the standard, so it appears at first glance that you explicitly initialised all members with the 0
that you wrote, but you didn't.
That place where you wrote 0
only affects the first member. So when, one day, you changed it to 1
thinking that it'll change all members, you'll have a bug, like here. It's misleading/dangerous/silly/fragile code.
For that reason, without an accompanying explanatory comment, = {0}
will not pass code review in my team. You should originally have written:
T t = {};
And now, to solve your problem according to the new requirements, you should write:
T t = {1,1,1};
or, if you don't mind your struct
potentially losing POD-ness, give T
a constructor.
[C++11: 8.5.1/2]:
When an aggregate is initialized by an initializer list, as specified in 8.5.4, the elements of the initializer list are taken as initializers for the members of the aggregate, in increasing subscript or member order. Each member is copy-initialized from the corresponding initializer-clause. If the initializer-clause is an expression and a narrowing conversion (8.5.4) is required to convert the expression, the program is ill-formed. [..]
[C++11: 8.5.1/6]:
An initializer-list is ill-formed if the number of initializer-clauses exceeds the number of members or elements to initialize.
[C++11: 8.5.1/7]:
If there are fewer initializer-clauses in the list than there are members in the aggregate, then each member not explicitly initialized shall be initialized from an empty initializer list (8.5.4).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With