Типичные диапазоны символов в большинстве систем:
- Тип: символ , диапазон: -127 до 127 или 0 до 255
- Тип: символ без знака , диапазон: от 0 до 255
- Тип: знаковый символ , диапазон: -127 до 127
Является ли char
со знаком или без знака определяется реализацией. Вы можете проверить, используя std::is_signed<char>()
. В вашем случае это неявно подписано , и компилятор обнаружил, что вы неявно преобразуете из положительного целого числа (10110000 = 176) в значение со знаком (где 10110000 равно -90). Предупреждение не будет сгенерировано, если значения меньше или равны 127 (попробуйте!).
Если вы хотите избежать неявного преобразования (сужающего преобразования), вы можете явно указать, что оно unsigned :
unsigned char m1[3]{ 176, 118, 1 };
Если вы хотите использовать подписанных символов , вам лучше использовать модификатор signed
, а не полагаться на реализацию:
signed char m1[3]{ b, 118, 1 }; // where b is less than or equal to 127
При {} -инициализации компилятор должен - по крайней мере - диагностировать его как предупреждение, что делает программу плохо сформированной. Но опять же, это зависит от компилятора и используемых опций. Если вы перейдете на https://gcc.godbolt.org/ и скомпилируете свой код с разными компиляторами / опциями, вы увидите разницу.
Некоторые примеры:
Для следующего кода:
char m1[3] = {176, 118, 1 };
- с x86-64 gcc 6.1 вы получаете ошибку:
error: narrowing conversion of '176' from 'int' to 'char' inside { } [-Wnarrowing]
. Однако, когда вы используете флаг -Wno-narrowing
, вы его не получаете, но, тем не менее, ваша программа плохо сформирована, и вы этого не хотите.
- с x86-64 gcc 4.8.1 вы не получите ни ошибок, ни предупреждений. Однако, используя, например, опции
-Wno-narrowing
или -Werror=narrowing
, вы можете видеть, что он отклонен с предупреждением или ошибкой соответственно.
С кодом:
int b1 = 176;
char m1[3] = {b1, 118, 1 };
Вы получаете различное поведение с разными версиями компилятора, но, тем не менее, программа некорректна.
В общем, использование таких опций, как -Wnarrowing
, -Wall
или -Werror=narrowing
с любой версией (я думаю, я не проверял все из них) компилятора, должно указывать на сужающее преобразование, что означает что ваша программа плохо сформирована, и вы этого не хотите.
Надеюсь, это поможет!