We can initialize the variable in two ways in C++11
One:
int abc = 7;
Two:
int abc {7};
What is the difference between these two methods?
How compiler treats them differently or the way these codes are executed?
Since C++11 we have uniform brace-init syntax which lets initialize objects using {} instead of () . I have read that as of now, {} is recommended because it disallows narrowing convertions and can be applied to types without any declared constructors.
If a class has non-default constructors, the order in which class members appear in the brace initializer is the order in which the corresponding parameters appear in the constructor, not the order in which the members are declared (as with class_a in the previous example).
In programming, curly braces (the { and } characters) are used in a variety of ways. In C/C++, they are used to signify the start and end of a series of statements. In the following expression, everything between the { and } are executed if the variable mouseDOWNinText is true. See event loop.
The code above shows how curly braces can be used to declare various types of variables and assign values to them. Using curly braces instead of an = sign is one of the many ways to initialize. Using curly braces to initialize a variable also prevents narrowing.
Initialization via {..}
is list-initialization, which prohibits narrowing conversions. For example, if LLONG_MAX
is the maximum value of an long long int
, and your int
cannot represent that:
int x = LLONG_MAX; // probably accepted with a warning int x {LLONG_MAX}; // error
Similarly:
long long y = /*something*/; int x = y; // accepted, maybe with a warning int x {y}; // error
An initialization of the form
T x = a;
is copy-initialization; an initialization of either form
T x(a); T x{a};
is direct-initialization, [dcl.init]/15-16.
[dcl.init]/14 then says:
The form of initialization (using parentheses or
=
) is generally insignificant, but does matter when the initializer or the entity being initialized has a class type; see below.
So for non-class types, the form of the initialization doesn't matter. However, there's a difference between these two direct-initializations:
T x(a); // 1 T x{a}; // 2
and similarly, between these two copy-initializations:
T x = a; // 1 T x = {a}; // 2
Namely, the ones with {..}
use list-initialization. The {..}
is called a braced-init-list.
So, when you compare T x = a;
to T x {a};
, there are two differences: copy- vs. direct-initialization, and "non-list-" vs. list-initialization. As already mentioned by others and in the quote above, for non-class types T
, there's no difference between copy- and direct-init. However, there's a difference between list-init and no list-init. That is, we could as well compare
int x (a); int x {a};
List-initialization in this case prohibits narrowing conversions. Narrowing conversions are defined in [dcl.init.list]/7 as:
A narrowing conversion is an implicit conversion
from a floating-point type to an integer type, or
from
long double
todouble
orfloat
, or fromdouble
tofloat
, except where the source is a constant expression and the actual value after conversion is within the range of values that can be represented (even if it cannot be represented exactly), orfrom an integer type or unscoped enumeration type to a floating-point type, except where the source is a constant expression and the actual value after conversion will fit into the target type and will produce the original value when converted back to the original type, or
from an integer type or unscoped enumeration type to an integer type that cannot represent all the values of the original type, except where the source is a constant expression whose value after integral promotions will fit into the target type.
While for int
the existing replies are complete, I painfully found out, that in some cases, there are other differences between the ()
and {}
initializations.
The keyword is that {}
is an initializer list.
One such cases is, the std::string
initialization with count
copies of a char
:
std::string stars(5, '*')
will initialize stars
as *****
, but
std::string stars{5, '*'}
will be read as std::string stars(char(5), '*')
and initialize star as *
(preceded by an hidden character).
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