Целочисленная константа 18446744073709551615
слишком велика, чтобы ее можно было представить в вашей системе как int
, long int
или long long int
.Компилятор предупреждает вас о том, что он делает его unsigned long long
.
Давайте попробуем скомпилировать эту программу вместо этого:
#include <stdio.h>
int main() {
if (-1 < 18446744073709551615)
printf("TRUE\n");
else
printf("FALSE\n");
return 0;
}
gcc
выдаст предупреждение:
#1 with x86-64 gcc 8.2
<source>: In function 'main':
<source>:7:14: warning: integer constant is so large that it is unsigned
if (-1 < 18446744073709551615)
^~~~~~~~~~~~~~~~~~~~
И вывод программы такой:
TRUE
clang
генерирует более явное предупреждение:
#1 with x86-64 clang 7.0.0
<source>:7:14: warning: integer literal is too large to be represented in a signed integer type, interpreting as unsigned [-Wimplicitly-unsigned-literal]
if (-1 < 18446744073709551615)
^
Но вывод программы:
FALSE
Если 18446744073709551615
действительно интерпретируется как беззнаковое, как будто написано 18446744073709551615u
или 0xffffffffffffffff
, сравнение должно выполняться с использованием арифметики без знака и завершается неудачно, поскольку оба числа имеют одинаковое значение.clang
делает то, что говорит, но gcc
не делает.
В вашем случае сохранение значения в переменной unsigned long
должно привести к ожидаемому результату, но добавление суффикса u
к константегарантирует, что он будет проанализирован компилятором с правильным типом.
Обратите внимание, однако, что вы можете получить максимальное значение любого типа без знака, приведя -1
к этому типу.Вы также можете использовать макросы, определенные в <limits.h>
: максимальное значение для типа unsigned long
равно ULONG_MAX
.