5

You can initialize a variable using = . For example:

int a = 1000;

C++ 11 introduced an extra notation {} . For example:

int a {1000};

According to Programming: Principles and Practices by Bjarne Stroustrup:

C++11 introduced an initialization notation that outlaws narrowing conversions.

I wanted to check out this cool feature. And I typed a piece of code twice:

#include "std_lib_facilities.h"     |     #include "std_lib_facilities.h" 
                                    |
int main()                          |     int main()
                                    |
{                                   |     {
    int x = 254;                    |         int x {254};
    char y = x;                     |         char y {x};
    int z = y;                      |         int z {y};
                                    |
    cout << "x = " << x << '\n'     |         cout << "x = " << x << '\n'
         << "y = " << y << '\n'     |              << "y = " << y << '\n'
         << "z = " << z << '\n';    |              << "z = " << z << '\n';
                                    |
}                                   |     }

The code on the left uses = whereas the code on the right uses {}

But the code on the right hand side loses some information even after using {}. Thus the output is same in both pieces of code:

x = 254

y = ■

z = -2

So, what's the difference between initializing with = and initializing with {} ?

EDIT: My question may or may not be a duplicate. I'm just a beginner and I do not even understand the code of the possibly original question. I'm no judge. Even if it's a duplicate, I cannot understand any answers of that question. I feel that this question should be treated as an original one since I would understand simple language opposed to some high-level words of that question's answer.

Community
  • 1
  • 1
Superex
  • 199
  • 1
  • 10
  • And where, exactly, do you expect a "narrowing conversion" to fail in the right example? The initialization of `char` with a positive number larger than `CHAR_MAX` on your machine? – DevSolar Mar 30 '16 at 14:52
  • 1
    `char` (in your system) default to `signed char` (but note that `signed char` != `char`). `254` is a valid `char` (no narrowing conversion, its numeric value doesn't matter) but converting back to `int` you get it negative because of sign. To see what's changed try `unsigned char k = {260};` vs `unsigned char k = 260;` – Adriano Repetti Mar 30 '16 at 14:54
  • If you use `gcc` add `-Werror=narrowing` command line option to outlaw the narrowing conversions. – Maxim Egorushkin Mar 30 '16 at 15:00
  • Adriano Repetti, I did stuff as you said. I think I must have made an error somewhere because the new source code did not work. I'm a beginner, so I have no idea about unsigned and signed. – Superex Mar 30 '16 at 15:05
  • 1
    Possible duplicate of [Is there a difference in C++ between copy initialization and direct initialization?](http://stackoverflow.com/questions/1051379/is-there-a-difference-in-c-between-copy-initialization-and-direct-initializati) – davidhigh Mar 30 '16 at 15:24
  • Davidhigh, I have made a few edits. – Superex Mar 30 '16 at 15:30
  • @Superex: just to clarify, that means no offense. Your question is valid. It's just that `{ ... }` corresponds to [direct-initialization](http://en.cppreference.com/w/cpp/language/direct_initialization) and `= ...` to [copy initialization](http://en.cppreference.com/w/cpp/language/copy_initialization), and the comparison between the two has already been treated here on SO. – davidhigh Mar 30 '16 at 16:03

1 Answers1

7

What is the difference between initializing with = and initializing with {}?

In general, the difference is that the former is copy initialization and the latter is direct - list initialization. The linked online reference describes all three forms of initialization in detail. In particular, there is the difference that you already quoted; List initialization may not be used with narrowing conversions.

But the code on the right hand side loses some information even after using {}

The program on the right side is ill-formed.

As mentioned, the standard does not allow narrowing conversions in the context of list initialization. int to char is a narrowing conversion.

Because the program is ill-formed, the standard does not guarantee its behaviour except that a compiler is required to emit a diagnostic message. For example, g++-5.3.0 will say:

warning: narrowing conversion of 'x' from 'int' to 'char' inside { } [-Wnarrowing]

May you please elaborate on the "ill-formed" part?

Standard says that the program shall not do X. Your program does X. Therefore it violates the standard which makes the program ill-formed. Here, X is:

If a narrowing conversion (see below) is required to convert any of the arguments, the program is ill-formed.


The program on the left is not ill-formed. However it, just like the program on the right side, does assign a value to char y that is not representable by the char type (it could be representable in some implementation where char is an unsigned type, but given the output, that appears not to be the case for your implementation). When an unrepresentable value is converted to a signed type, the resulting value is implementation defined.

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
eerorika
  • 232,697
  • 12
  • 197
  • 326
  • Yep, I got that warning message! May you please elaborate on the "ill-formed" part? Thanks for the answer though! – Superex Mar 30 '16 at 15:35
  • @Superex I added a simple explanation for ill-formedness. – eerorika Mar 30 '16 at 15:40
  • Thanks for elaborating on that part. But I have used a library (std_lib_facilities.h) that has been suggested by the book. So I doubt that program may be ill-formed. – Superex Mar 30 '16 at 15:43
  • @Superex why do you think that including that header prevents your program from being ill-formed? It does not. You said that you got the warning message. The warning implies that your program is ill-formed. – eerorika Mar 30 '16 at 15:48
  • I deleted my previous comment. I accidentally copy-pasted the wrong diagnostics. But I did get what you mentioned in another similar experiment. – Superex Mar 30 '16 at 18:37