Basically, why is this valid:
auto p1 = new int[10]{5};
but this is not:
auto p1 = new int[10](5);
And more generally what are the rules for the new-expression initializer?
I found the following:
— If the new-initializer is omitted, the object is default-initialized (8.5). [ Note: If no initialization is performed, the object has an indeterminate value. — end note ] — Otherwise, the new-initializer is interpreted according to the initialization rules of 8.5 for direct- initialization.
So is the second case invalid because smth like T((5))
is invalid (direct initialization from expression (5)
)? Or what is the reason?
EDIT: well, my suggestion of (())
thing seems dumb because I see no reason why that should only apply to array new-expression.
Initializer List: To initialize an array in C with the same value, the naive way is to provide an initializer list. We use this with small arrays. int num[5] = {1, 1, 1, 1, 1}; This will initialize the num array with value 1 at all index.
The entire array can be initialized to zero very simply. This is shown below. int arr[10] = {0};
Direct Initialization or Assignment Operator (Syntax) This assigns the value of one object to another object both of which are already exists. Copy initialization is used when a new object is created with some existing object. This is used when we want to assign existing object to new object.
The 1st one is valid because of list initialization (since C++11),
new T { arg1, arg2, ... }
and
If T is an aggregate type, aggregate initialization is performed.
int[10]
is an array type which belongs to aggregate type, then aggregate initialization is performed,
If the number of initializer clauses is less than the number of members
and bases (since C++17)
or initializer list is completely empty, the remaining membersand bases (since C++17)
are initializedby their default initializers, if provided in the class definition, and otherwise (since C++14)
by empty lists, in accordance with the usual list-initialization rules (which performs value-initialization for non-class types and non-aggregate classes with default constructors, and aggregate initialization for aggregates). If a member of a reference type is one of these remaining members, the program is ill-formed.
So auto p1 = new int[10]{5};
will create a pointer to array, whose first element is initialized as 5
, the remaining elements are initialized as 0
.
The 2nd one is direct initialization, so new int[10](5);
means initialize the array int[10]
from a single int
5
directly; which is invalid.
In fact, for the array new expression you can't specify a non-empty parenthesized initializer.
If type is an array type, an array of objects is initialized.
- If initializer is absent, each element is default-initialized
- If initializer is an empty pair of parentheses, each element is value-initialized.
- If initializer is a brace-enclosed list of arguments, the array is aggregate-initialized. (since C++11)
So
auto p1 = new int[10]; // valid
auto p2 = new int[10](); // valid
auto p3 = new int[10]{5}; // valid
auto p4 = new int[10](5); // invalid
From the point view of the standard, as you quoted, [expr.new]/18:
A new-expression that creates an object of type T initializes that object as follows:
- If the new-initializer is omitted, the object is default-initialized ([dcl.init]). [ Note: If no initialization is performed, the object has an indeterminate value. — end note ]
=> Applies for auto p1 = new int[10];
, leads to default-initialization.
- Otherwise, the new-initializer is interpreted according to the initialization rules of [dcl.init] for direct-initialization.
And [dcl.init]/17:
- (17.1) If the initializer is a (non-parenthesized) braced-init-list or is = braced-init-list, the object or reference is list-initialized.
=> Applies for auto p3 = new int[10]{5};
, leads to list initialization, details are explained above.
- (17.4) If the initializer is (), the object is value-initialized.
=> Applies for auto p2 = new int[10]();
, leads to value initialization.
- (17.5) Otherwise, if the destination type is an array, the program is ill-formed.
=> Applies for auto p4 = new int[10](5);
.
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