Converting to std :: array <unsigned char, 1ul> :: value_type from int can change its value

The -Wconversion GCC parameter generates a warning from the header when compiling this program:

 #include <iostream> #include <array> #include <string> int main () { std::string test = "1"; std::array<unsigned char, 1> byteArray; byteArray[0] = byteArray[0] | test[0]; return 0; } 

Here's how I compile it: g++- -Wall -Wextra -Wconversion -pedantic -std=c++0x test.cpp and I use GCC 4.5.

Am I doing something illegal here? Could this cause problems in certain scenarios? Why | creates an int ?

+8
c ++ gcc bitwise-operators char type-conversion
source share
3 answers

Am I doing something illegal here?

You are converting from a signed type to an unsigned type. If the signed value was negative, an unsigned result would be a non-negative value determined by implantation (and therefore not the same as the initial value).

Could this cause problems in certain scenarios?

Only if the value can be negative. This may be on some exotic architectures where sizeof (char) == sizeof (int) , or if your code did something more complex than combining two values ​​with | .

Why | will create int ?

Because all integer values ​​are advanced before being used in arithmetic operations. If their type is less than int , then they advance to int . (There's a bit more to promotion than this, but this is a rule relevant to this issue).

+6
source share

yes, the string consists of char, which is signed, you have an unsigned array of char.

as for | producing int, it is called the whole promotion. basically the compiler does both of them int, does a, and then does them char again.

However, the problem is facing this. By C / C ++ standards, integer promotion occurs if the type being propagated can contain all the values ​​of the type being promoted with. therefore, it supports unsigned char for unsigned int and signed char for signed int. Promotion of a sign of a symbolic sign - expands it. So say that you have -1 or 0xFF or 11111111. This is expanded to 10000000000000000000000001111111, signed int ((int) -1). Obviously, it will have a different result than when used with 11111111 ((char) - 1) to intuitively expect.

See here for more information: here he explains a peculiar "workaround"

+2
source share

unsigned char | char result unsigned char | char unsigned char | char is int for whole conversion rules . When you assign an int back to an unsigned char , an assignment can truncate its int value - the compiler does not know how large the value you have in that int .

To disable the compiler:

byteArray[0] = static_cast<unsigned char>(byteArray[0] | test[0]);

+2
source share

All Articles