Create array of chars avoiding narrowing
Asked Answered
D

1

7

I am writing a unit test checking some binary data against an expected array. The expected array in question is just some series of bytes, doesn't matter specifically:

char expected[] = {0x42, 0xde, 0xad, 0xbe, 0xef};

This compiled fine in C++, but with C++11 this issues a warning on narrowing conversion. I compile with -Werror because warnings matter, so that line does not compile for me. As far as I'm aware, there's no literal suffix for char, so it seems I'd have to do:

char expected[] = {static_cast<char>(0x42), static_cast<char>(0xde), ... };

That seems pretty unwieldy to me. Is there a better way to construct this character array? (Outside of either removing -Werror or adding -Wno-narrowing).

Dolhenty answered 22/1, 2015 at 16:49 Comment(2)
The bytes should be declared as unsigned char or uint8_t.Shaker
the signess of char is implementation specific. If you get this error means that those values don't fit in a char meaning the char is signed on your platform. Regardless, for compatibility you should declare unsigned char or uint8_t as specified before for variables meant to hold byte values.Liable
T
8

So C++11 has an exception for integer types and unscoped enums for constant expressions that fit after promtion in the target type, the draft C++11 standard section 8.5.4 [dcl.init.list] says:

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.

The problem here is that some of the values do not fit into char if you use unsigned char instead it should work.

clang is a little more helpful in that it warns which specific elements generate the warning and in this case it does not warn for 0x42 but does for the rest, for example:

error: constant expression evaluates to 222 which cannot be narrowed to type 'char' [-Wc++11-narrowing]
char expected[] = {0x42, 0xde, 0xad, 0xbe, 0xef};
                         ^~~~
Thrave answered 22/1, 2015 at 16:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.