Чтобы понять, почему buffer[0] == 0xef
вызывает предупреждение, а buffer[0] == 0xffffffef
нет, вам нужно точно понять, что происходит в этом выражении.
Во-первых, оператор ==
сравнивает значение двух выражений, а не базовое представление - 0xef
- это число 239, и будет сравниваться только равное этому числу; аналогично 0xffffffef
- это число 4294967279, и оно будет сравниваться только с ним.
Нет разницы между константами 0xef
и 239
в C: оба имеют тип int
и одно и то же значение. Если ваш char
имеет диапазон от -128 до 127, то при оценке buffer[0] == 0xef
значение buffer[0]
повышается до int
, что оставляет его значение без изменений. Поэтому он никогда не может сравниваться равным 0xef
, поэтому предупреждение верно.
Однако - это потенциально разница между константами 0xffffffef
и 4294967279; десятичные константы всегда подписаны, но шестнадцатеричная константа может быть без знака. В вашей системе он имеет тип без знака - вероятно, unsigned int
(поскольку значение слишком велико для хранения в int
, но достаточно мало для хранения в unsigned int
). Когда вы оцениваете buffer[0] == 0xffffffef
, buffer[0]
повышается до unsigned int
. Это оставляет любое положительное значение без изменений, но отрицательные значения преобразуются путем добавления к ним UINT_MAX + 1
; с char
, который имеет диапазон от -128 до 127, повышенные значения находятся в любом из диапазонов от 0 до 127 или от 4294967168 до 4294967295. 0xffffffef
лежит в этом диапазоне, поэтому сравнение может вернуть true.
Если вы храните битовые комбинации, а не числа, то вам следует использовать unsigned char
в первую очередь. В качестве альтернативы вы можете проверить битовую комбинацию объекта, указав на него указатель unsigned char *
:
if (((unsigned char *)buffer)[0] == 0xef)
(Очевидно, это удобнее сделать, используя отдельную переменную типа unsigned char *
).
Как говорит PaulR , вы также можете использовать buffer[0] == '\xef'
- это работает, потому что '\xef'
определена как константа int
со значением, которое char
объект с битовой комбинацией 0xef имел бы при преобразовании в Int; например. в системе дополнения 2s со знаковыми символами '\xef'
является константой со значением -17.