In C++11, both of the following statements are legal:
statement 1. int a[8] = {};
statement 2. int a[8]{};
However, I like statement 1 better than statement 2 because I think statement 1 is more expressive.
Does the C++11 standard guarantee that both statements are semantically equivalent?
Semantically, they are not the same, much like copy/direct initialization:
1 List-initialization is initialization of an object or reference from a braced-init-list. Such an initializer is called an initializer list, and the comma-separated initializer-clauses of the list are called the elements of the initializer list. An initializer list may be empty. List-initialization can occur in direct-initialization or copyinitialization contexts; list-initialization in a direct-initialization context is called direct-list-initialization and list-initialization in a copy-initialization context is called copy-list-initialization. [...] (emphasis mine)
Original answer, dealing with the comparative performance: No, the standard specifies some complexity restraints on algorithms, but not performance on such issues. This is better left to the compiler, but all compilers will likely generate the same code.
Think about copy-initialization vs direct-initialization. The standard specifies only what they are, it never says one has to be faster then the other or that they must behave the same. It's entirely up to the compiler.
And that's a good thing, because the compiler know what's best for that platform. If the standard did impose such restraints, it could say +
has to be faster than *
, which is pretty intuitive. But think of a platform built for multiplication, where it's actually faster to compute *
in machine code. The compiler would have to go out of its way to translate *
into a slower instruction, just to conform to the standards.
The Standard only defines so-called "observable behavior" which is the sequence of I/O library calls and reads and writes of volatile data. No speed requirements are there.
You can't be sure which is faster in practice. Decent compilers should emit the same code but sometimes there're bugs in compilers and those may affect code emission.
Yes, they are semantically equivalent.
List-initialization (8.5.4) on an aggregate (8.5.1, e.g. an array) performs aggregate initialization (8.5.4p3b1). Aggregate initialization does not care whether the syntactic form is that of direct-initialization or copy-initialization; the rules of aggregate initialization apply identically in either case. In particular, the members of the aggregate are always copy-initialized from the corresponding clause of the initializer list.
There is an exception, which almost but not quite applies in your case; where there are insufficient elements to initialize all members of the aggregate, the standard is unclear on how to initialize the remaining members; they are list-initialized from {}
(the empty list-initializer) but it is not specified whether they are copy-list-initialized or direct-list-initialized, or whether this depends on the original list-initialization (see comments); in fact, clang and gcc differ on their behaviour in this corner case. However, this is irrelevant in your case, since the aggregate member type is int
, and for nonclass types list-initialization from {}
invokes value-initialization i.e. zero-initialization, which is direct regardless of the syntactic form (i.e., int i{};
and int i = {};
are semantically identical).
There are a few reasons to prefer the =
(copy-initialization) syntax: first, it is the form used by the standard in almost all examples (the exceptions being the last two examples in 8.5.4p3, where one demonstrates an error in narrowing conversion and the other demonstrates initialization from an empty initializer-list). Also, as you have said, it is more expressive; I also find that when list-initializing an aggregate, the copy-initialization syntax better reflects the fact that the elements of the aggregate are themselves copy-initialized.
Finally, the syntax without =
is necessary in one case: where the object is a non-aggregate class type with an explicit
constructor. As such, the direct-list-initialization syntax should be reserved for that case.
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