В языке C арифметические аргументы троичного оператора ?:
подвергаются обычным арифметическим преобразованиям, т. Е. Они повышаются до int
перед выполнением любых дальнейших вычислений. Не имеет значения, являются ли они постоянными или нет. Важно то, что они имеют тип unsigned char
(как вы сказали), и unsigned char
в ?:
всегда продвигается первым. По сути, язык C никогда не выполняет никаких вычислений в типах, меньших int
. Все, что меньше, сначала преобразуется в int
.
Это то, что происходит и в вашем случае. В основном, ваш
a = (b == B1) ? A1 : A2;
интерпретируется языком C как
a = ((int) b == (int) B1) ? (int) A1 : (int) A2;
и вот почему вы получаете предупреждение. Опять же, тот факт, что A1
и A2
являются константами, не играет никакой роли.
a = A1;
не подвергает правую часть интегральному продвижению, поэтому здесь нет никаких предупреждений. Более того, в этом тривиальном случае (прямое присваивание), даже если A1
было явно объявлено как константа int
, большинство компиляторов не будут выдавать предупреждение, если увидят, что константа находится в диапазоне целевого типа unsigned char
. Случай с ?:
более сложный, поэтому компиляторы могут вернуться к общему поведению и выдать предупреждение.