Если sizeof (long) составляет 4 байта на моей машине, могу ли я сделать вывод, что sizeof (long long) будет 8 байтов? - PullRequest
2 голосов
/ 18 января 2020
printf("Size of long int: %zu\n" , sizeof(long));
printf("Size of long long int: %zu\n" , sizeof(long long));

При запуске на моей 64-битной машине вывод:

Size of long int: 8
Size of long long int: 8

1 Ответ

3 голосов
/ 18 января 2020

Это зависит .

Стандартно, в общем случае вы ничего не можете сказать о размере типа из размера другого типа, если не нижняя граница (в зависимости от значения CHAR_BIT). Ниже приведен более подробный ответ.

В отношении реализации, если компилятор соответствует стандарту и значение CHAR_BIT равно 8 (что наиболее часто используется), тогда sizeof long должно быть как минимум 4, а sizeof long long должно быть как минимум 8. Оставляя в стороне архитектуры esoteri c, в которых появляются странные биты заполнения (например, процессор Itanium с его зарезервированным битом "Не вещь"), имеет смысл предположить, что sizeof long long равно 8 при таких обстоятельствах.

В случае G CC для Intel x86 и ARM, например, AFAIK это предположение верно, поэтому ответом на ваш вопрос будет "да". Тем не менее, я бы настоятельно рекомендовал не делать никакого выбора дизайна, основываясь на таком простом предположении, которое можно легко протестировать во время компиляции, например:


Стандартно, точнее: C Стандарт не предписывает никаких правил относительно того, каким должен быть размер целочисленного типа. Он определяет только минимальный диапазон значений , который тип должен представлять. Для C99 эти значения указаны в ISO / IEC 9088: 1999 §5.2.4.2 «Числовые пределы» ( стр. 21 здесь ).

Единственное неявное требование к размеру целочисленных типов со знаком приведено в §6.2.6.2 «Целочисленные типы»:

  1. Для целочисленных типов без знака, отличных от unsigned char, биты представление объекта должно быть разделено на две группы: биты значения и биты заполнения (не должно быть ни одной из последних). Если имеется N битов значения, каждый бит должен представлять различную степень 2 от 1 до 2 ^ (N-1), так что объекты этого типа должны быть способны представлять значения от 0 до 2 ^ (N-1) с использованием чисто двоичное представление; это должно быть известно как представление значения. Значения любых битов заполнения не определены.

  2. Для целочисленных типов со знаком биты представления объекта должны быть разделены на три группы: биты значения, биты заполнения и бит знака. Там не должно быть никаких битов заполнения; должен быть ровно один знаковый бит. Каждый бит, который является битом значения, должен иметь то же значение, что и тот же бит в представлении объекта соответствующего типа без знака (если имеется M битов значения в типе со знаком и N в типе без знака, то M ≤ N).

Первая точка неявно устанавливает нижнюю границу для числа бит целочисленного типа: поскольку стандарт определяет минимальные диапазоны значений, которые эти типы должны представлять, и также заявляет, что для такого значения должно быть ровно N битов, мы знаем, что каждый целочисленный тип должен иметь размер не менее N битов, чтобы можно было представлять значения от 0 до 2 ^ (N-1).

Однако, учитывая наличие «битов заполнения», не дает никакой гарантии на верхней границе для размера целочисленных типов. Поэтому, как правило, не только нет гарантии , что sizeof long == 4 подразумевает sizeof long long == 8, но также нет гарантии , что sizeof long long >= sizeof long в первую очередь. Это также относится к другим целочисленным типам.

Что касается стандарта, совместимая реализация может даже иметь:

  • CHAR_BIT == 8
  • sizeof int == 10, с 31 бит для значения, 1 для знака и 47 для заполнения
  • sizeof long == 8, с 63 битами для значения, 1 для знака и 0 для заполнения.
...