Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create array of chars avoiding narrowing

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).

like image 479
Barry Avatar asked Jan 22 '15 16:01

Barry


1 Answers

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};
                         ^~~~
like image 184
Shafik Yaghmour Avatar answered Nov 11 '22 05:11

Shafik Yaghmour