Consider the code below
struct B
{
B() : member{}{};
int member[10];
};
int main()
{
B b;
}
VS2013 compiler gives the following warning:
warning C4351: new behavior: elements of array 'B::member' will be default initialized 1> test.vcxproj -> C:\Users\asaxena2\documents\visual studio 2013\Projects\test\Debug\test.exe
This is documented here
With C++11, and applying the concept of 'default initialization', means that elements of B.member will not be initialized.
But I believe that member{}
should perform value initialization and not default initialization. Is the VS2013 compiler broken?
$8.5/6
To default-initialize an object of type
T
means: — ifT
is a (possibly cv-qualified) class type (Clause 9), the default constructor forT
is called (and the initialization is ill-formed ifT
has no accessible default constructor);
— ifT
is an array type, each element is default-initialized;
— otherwise, no initialization is performed.
If a program calls for the default initialization of an object of aconst
-qualified typeT
,T
shall be a class type with a user-provided default constructor.
$8.5.1
List-initialization of an object or reference of type
T
is defined as follows:
— If the initializer list has no elements andT
is a class type with a default constructor, the object is value-initialized.
— Otherwise, ifT
is an aggregate, aggregate initialization is performed (8.5.1).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). [ Example:
struct S { int a; const char* b; int c; }; S ss = { 1, "asdf" };
initializes
ss.a
with1
,ss.b
with"asdf"
, andss.c
with the value of an expression of the formint()
, that is,0
. —end example ]
For an array of pointers, the default value is nullptr . For strings, the default value is an empty string "" . That's all about declaring and initializing arrays in C/C++.
In computer programming, initialization (or initialisation) is the assignment of an initial value for a data object or variable. The manner in which initialization is performed depends on the programming language, as well as the type, storage class, etc., of an object to be initialized.
As default constructor initializes the data members of class to 0.
It seems to be an incorrectly worded warning message (and I'm surprised it is printing a warning in the first place), but the behavior is correct. B::member
is being value initialized, which for an array of int
turns into zero initialization. This can be demonstrated using the following:
#include <iostream>
struct B
{
B() : member{}{};
int member[10];
};
struct C
{
C() {};
int member[10];
};
int main()
{
B b;
for(auto const& a : b.member) std::cout << a << ' ';
std::cout << std::endl;
C c;
for(auto const& a : c.member) std::cout << a << ' ';
std::cout << std::endl;
}
If you compile and run in Debug mode this results in the output:
0 0 0 0 0 0 0 0 0 0
-858993460 -858993460 -858993460 -858993460 -858993460 -858993460 -858993460 -858993460 -858993460 -858993460
The numbers in the second line are 0xCCCCCCCC
, the debug pattern the VC++ compiler fills memory with in Debug mode. Thus B::member
is being zero-initialized, while no initialization is performed for C::member
.
Disclaimer: I know that reading from an uninitialized variable is undefined behavior, but this is the best proof I could come up with.
The compiler warning is incorrect; it is actually performing value-initialization as required by the standard.
Example:
#include <iostream>
struct B {
B() : member{}{};
int member[10];
};
int main() {
int a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
B &b = *new (a) B;
std::cout << b.member[9]; // prints '0'
}
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