Is this list-initialization of an array of unknown size valid in C++0x?
Is this list-initialization of an array of 开发者_运维知识库unknown size valid in C++0x?
int main() { int x[]{0, 1,2,3,4}; return x[0]; }
I believe it is valid, but would appreciate some confirmation.
If anyone could quote from the C++0x-FCD to support their case, it would be greatly appreciated.
Thanks!
This goes from 8.5/16
first bullet to 8.5.4
list-initialization and from 8.5.4/3
third bullet to 8.5.1
aggregate initialization and then 8.5.1/4
says
An array of unknown size initialized with a brace-enclosed initializer-list containing n initializer-clauses, where shall be greater than zero, is defined as having elements
The only difference if the object is an array between = { ... }
and { ... }
is that the first is called copy-list-initialization and the second is called direct-list-initialization, so both are kinds of list-initialization. The elements of the array are copy-initialized from the elements of the initializer list in both cases.
Notice that there is a subtle difference between those forms if the array has a size and the list is empty, in which case 8.5.4
second bullet applies:
struct A {
explicit A();
};
A a[1]{}; // OK: explicit constructor can be used by direct initialization
A a[1] = {}; // ill-formed: copy initialization cannot use explicit constructor
This difference does not apply to lists that have content in which case third bullet applies again, though
struct A {
explicit A(int);
};
A a[1]{0}; // ill-formed: elements are copy initialized by 8.5.1
A a[1] = {0}; // ill-formed: same.
The FCD changed this compared to the previous draft, and initialization with an empty initializer list now always works even with explicit default constructors. This is because the FCD states that the elements are value-initialized, and value initialization doesn't care about explicitness since it doesn't do overload resolution on default constructors (it couldn't figure out better or worse matches anyway). The previous draft used normal overload resolution on the constructors and thus rejected explicit default constructors during copy initialization. This defect report did that change.
Yes, it is valid, and has been for decades, even in C. The size is simply set to the number of elements supplied. I don't know the reference, unfortunately.
(Added bonus...) If you need the number of elements use sizeof(x)/sizeof(*x)
. It's safer than hard-coding a constant that may become invalid if you add or remove entries.
EDIT: As pointed out in the comments, the code in question is missing an =
(a fact that I missed), without which it isn't valid in any current standard of C or C++.
精彩评论