У меня есть код здесь:
#include <stdio.h>
int main ()
{
char foo = 0xE7;
if (foo == 0xE7)
printf ("true\n");
else
printf ("false\n");
return 0;
}
Это печатает «ложь». Я не слишком обеспокоен этим, потому что я могу поверить, что foo содержит 0xE7, который теперь считается подписанным (-25) и сравнивает false с 0xE7 — который равен 231 в десятичном виде.
Но как насчет этого?
#include <stdio.h>
int main ()
{
char c = 0xE7;
if (c == 0xFFFFFFE7)
printf ("true\n");
else
printf ("false\n");
return 0;
}
Это печатает «правда».
Согласно стандарту C ++:
Шестнадцатеричный целочисленный литерал (основание шестнадцать) начинается с 0x или 0X и состоит из последовательности шестнадцатеричных цифр, которые включают десятичные цифры и буквы от a до f и от A до F с десятичными значениями от десяти до пятнадцати.
А также:
Тип целочисленного литерала является первым из соответствующего списка в Таблице 6, в котором может быть представлено его значение.
Первый пункт в списке — «int». И так как сравнение верно, может показаться, что 0xFFFFFFE7 == -25.
Тем не менее, 0xFFFFFFE7 — это еще один способ написания 4294967271. Итак, давайте попробуем:
#include <stdio.h>
int main ()
{
char c = 0xE7;
if (c == 4294967271)
printf ("true\n");
else
printf ("false\n");
return 0;
}
Это печатает «ложь». Итак, 0xFFFFFFE7 — это не то же самое, что 4294967271.
Возвращаясь к Стандарту, что на самом деле означают слова «в которых может быть представлена его ценность»? Ясно, что вы можете вставить 0xFFFFFFE7 в 4-байтовое целое со знаком, но это не совсем «представляет значение» 4294967271.
Тем не мение:
if (0xFFFFFFE7 == 4294967271) // --> prints "true"
Также:
if (-25 == 0xFFFFFFE7) // --> prints "true"
Таким образом, представляется, что «его значение может быть представлено» означает «на двоичном уровне», а не «обрабатывает шестнадцатеричную константу как ее эквивалентное десятичное число». Это звучит правильно?
Протестировано на gcc 4.8.2, Ubuntu 14.04, 64-битный процессор.
Задача ещё не решена.