3

I am trying to understand the full range of functionality of the {} initializer syntax.

I have compiled the following code with g++:

int i = 0;                /* OK */

short int si2 {i};        /* Warning: Narrowing Conversion inside {...} */

char myChar {127ULL};     /* OK */

char myChar2 {128ULL};    /* Warning: Narrowing Conversion inside {...} */

My understanding of the warning for the initialization of si2 is as follows. On my system: - short int is 2 bytes - int is 4 bytes

Because the initializer is twice the size (in bytes) as the LHS, this constitutes narrowing and therefore a compiler warning is given.

However for myChar and myChar2, both initializers have the same datatype: unsigned long long int. I believe that the initialization of myChar2 has occurred because the value of the initializer would be too large for the char datatype.

the same rules do not seem to apply in both of these cases: 1. Failure because initializer datatype too large for initialized variable 2. Failure because value is too large for initialized variable (although RHS datatype is acceptable here)

Is my understanding here correct - does the initializer list behave differently if the argument is an integer literal ?

1
  • What happens if you use constexpr int i = 0; instead? It should make it much simpler to statically determine if the initialization is problematic. Commented Oct 28, 2019 at 17:06

2 Answers 2

2

It seems your compiler by default considers the type char similarly to the type signed char.

In these declarations

char myChar {127ULL};     /* OK */

char myChar2 {128ULL};

the initializers have positive values and the positive value 128 can not be represented in an object of the type signed char.

The maximum positive value that can be represented by the type signed char is 127. That is the range of the values is [-128, 127].

So the compiler issues a warning.

For this statement

short int si2 {i}; 

the compiler issues a warning because the initializer is not a compile-time constant.

If you will write

const int i = 0;

then the warning disappears.

Sign up to request clarification or add additional context in comments.

1 Comment

Hi, thank you for your reply. Okay, I see now that if the initializer value is known at compile time, and is within the allowable range of the initialized variable then no warning is issued. If not known at compile time, and datatype is larger then a warning is issued.
0

Remember this thing.

When used with variables of built-in type, this form of initialization has one important property: The compiler will not let us list initialize variables of built-in type if the initializer might lead to the loss of information:

    long double ld = 5.14159265;
    int a{ld}, b = {ld}; // error: narrowing conversion required
    int c(ld), d = ld; // ok: but value will be truncated

The compiler rejects the initializations of a and b because using a long double to initialize an int is likely to lose data. At a minimum, the fractional part of ld will be truncated. In addition, the integer part in ld might be too large to fit in an int.

Now coming to last 2 parts. you defined char which is of signed type. It can hold values from -128 to 127.But you are trying to assign 128 and that's you got warning from compiler.

2 Comments

Hi, thanks for the reply. If the initializer-list prevents loss of information, why does char myChar {127ULL}; not give a warning ? Don't change of signed-ness , and datatype narrowing from Unsigned Long Long Int to Signed Char count as loss of information ?
@thatmarkdude Ideally we should always try to prevent any kind of data loss. So lists are doing their work by preventing but sometimes we know that data will be lost by our action but still we don't care about it and for that kind of scenarios parenthesis are used.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.