Ответ 1
Когда суффикс L
или UL
не используется, компилятор использует первый тип, который может содержать константу из списка (см. подробности в стандарте C99, раздел 6.4.4: 5. Для десятичной константы, список int
, long int
, long long int
).
Как следствие, в большинстве случаев нет необходимости использовать суффикс. Это не меняет смысл программы. Это не изменяет значение инициализации вашего примера x
для большинства архитектур, хотя это было бы, если бы вы выбрали число, которое не могло бы быть представлено как long long
. См. Также ответ codebauer для примера, где необходима часть U
суффикса.
Есть несколько обстоятельств, когда программист может захотеть явно указать тип константы. Одним из примеров является использование вариационной функции:
printf("%lld", 1LL); // correct
printf("%lld", 1); // undefined behavior
Общей причиной использования суффикса является то, что результат вычисления не переполняется. Два примера:
long x = 10000L * 4096L;
unsigned long long y = 1ULL << 36;
В обоих примерах без суффиксов константы имели бы тип int
, и вычисление было бы сделано как int
. В каждом примере это несет риск переполнения. Использование суффиксов означает, что вычисление будет выполняться в большем типе вместо этого, который имеет достаточный диапазон для результата.
Как утверждает Lightness Races в Orbit, суффикс litteral имеет значение до. В двух приведенных выше примерах просто объявить x
как long
и y
как unsigned long long
недостаточно для предотвращения переполнения при вычислении выражений, назначенных им.
Другим примером является сравнение x < 12U
, где переменная x
имеет тип int
. Без суффикса U
компилятор задает константу 12
как int
, и поэтому сравнение представляет собой сравнение подписанных int.
int x = -3;
printf("%d\n", x < 12); // prints 1 because it true that -3 < 12
С суффиксом U
сравнение становится сравнением беззнаковых int. "Обычные арифметические преобразования" означают, что -3 преобразуется в большой беззнаковый int:
printf("%d\n", x < 12U); // prints 0 because (unsigned int)-3 is large
Фактически, тип константы может даже изменить результат арифметического вычисления, опять же из-за того, как работают "обычные арифметические преобразования".
Обратите внимание, что для десятичных констант список типов, предложенный C99, не содержит unsigned long long
. В C90 список завершился самым большим стандартизованным целым типом без знака в то время (который был unsigned long
). Следствием было то, что значение некоторых программ было изменено путем добавления стандартного типа long long
к C99: та же самая константа, которая была набрана как unsigned long
в C90, теперь может быть введена как подписанная long long
. Я считаю, что именно по этой причине в C99 было принято решение не иметь unsigned long long
в списке типов для десятичных констант.
Для примера см. this и . p >