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
Tmeans: — ifTis a (possibly cv-qualified) class type (Clause 9), the default constructor forTis called (and the initialization is ill-formed ifThas no accessible default constructor);
— ifTis 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,Tshall be a class type with a user-provided default constructor.
$8.5.1
List-initialization of an object or reference of type
Tis defined as follows:
— If the initializer list has no elements andTis a class type with a default constructor, the object is value-initialized.
— Otherwise, ifTis 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.awith1,ss.bwith"asdf", andss.cwith 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