Любые гарантированные минимальные размеры для типов в C?

Можете ли вы вообще сделать какие-либо предположения о минимальном размере типа данных?

То, что я прочитал до сих пор:

  • char: 1 байт
  • short: 2 Byte
  • int: 2 байт, обычно 4 байта
  • long: 4 байт

поплавка??? двойная???

Являются ли значения в float.h и limits.h зависимыми от системы?

Ответ 1

Это описано в Статья в Википедии:

A short int не должно быть больше, чем int.
int не должен быть больше, чем long int.

A short int должен иметь длину не менее 16 бит.
int должен иметь длину не менее 16 бит.
A long int должен иметь длину не менее 32 бит.
A long long int должен иметь длину не менее 64 бит.

Стандарт не требует, чтобы любой из этих размеров был обязательно другим. Это совершенно справедливо, например, если все четыре типа имеют длину 64 бит.

Ответ 2

Да, значения в float.h и limits.h зависят от системы. Вы никогда не должны делать предположений о ширине типа, но стандарт устанавливает некоторые минимумы. См. §6.2.5 и §5.2.4.2.1 в C99 standard.

Например, в стандарте указано, что char должен быть достаточно большим, чтобы содержать каждый символ в наборе символов выполнения. Он не говорит, насколько он широк.

Для случая с плавающей запятой стандартные подсказки в том порядке, в котором указаны ширины типов:

§6.2.5.10

Существует три реальных типа, обозначаемых как float, double и long двойная. 32) Набор значений типа float представляет собой подмножество набора значений типа double; набор значений типа double является подмножеством набора значений типа long double.

Они неявно определены, которые шире, чем другие, но не конкретно, насколько они широки. Сам "подмножество" является неопределенным, так как a long double может иметь тот же самый диапазон a double и удовлетворять этому предложению.

Это довольно типично для того, как C идет, и много осталось для каждой отдельной среды. Вы не можете предположить, вы должны спросить у компилятора.

Ответ 3

Однако новый C99 указывает (в stdint.h) дополнительные типы минимальных размеров, такие как uint_least8_t, int_least32_t и т.д.
(см. en_wikipedia_Stdint_h)

Ответ 4

Если вы не отметили check, размер (в кратных символах) любого типа на вашей системе/платформе действительно соответствует ожидаемому размеру:

enum CHECK_FLOAT_IS_4_CHARS
{
   IF_THIS_FAILS_FLOAT_IS_NOT_4_CHARS = 1/(sizeof(float) == 4)
};

Ответ 5

Часто разработчики, задающие этот вопрос, занимаются организацией упакованного struct для соответствия определенному макету памяти (как и для протокола сообщений). Предполагается, что язык должен непосредственно указывать для этой цели 16-, 24-, 32-разрядные и т.д. Поля.

Это обычное и приемлемое для языков ассемблера и других языков приложений, тесно связанных с конкретной архитектурой процессора, но иногда это проблема на языке общего назначения, который может быть нацелен на то, кто знает, какую архитектуру.

Фактически, язык C не был предназначен для конкретной аппаратной реализации. Он был указан вообще, поэтому разработчик компилятора C мог правильно адаптироваться к реалиям конкретного процессора. Аппаратная архитектура Франкенштейна, состоящая из 9-битных байтов, 54-битных слов и 72-битных адресов памяти, легко и однозначно отображает функции C. (char - 9 бит, short int, int и long int - 54 бита.)

Эта общность заключается в том, почему спецификация C говорит что-то о влиянии "не ожидайте многого о размерах ints вне sizeof (char) <= sizeof (short int) <= sizeof (int) < =; = sizeof (long int)." Это означает, что символы могут быть того же размера, что и длинные!

Нынешняя реальность - и будущее, похоже, держится - требования к архитектуре программного обеспечения обеспечивают 8-битные байты, а слова памяти адресуются как отдельные байты. Это было не всегда так. Не так давно я работал над архитектурой CDC Cyber ​​с 6-битными байтами и 60-битными словами. Реализация C на этом будет интересна. Фактически, эта архитектура отвечает за странную семантику упаковки Pascal - если кто ее помнит.

Ответ 6

Цитата стандарта дает то, что определено как "правильный ответ", но на самом деле не отражает способ написания программ.

Люди делают предположения все время, когда char равно 8 бит, короткий - 16, int - 32, long - 32 или 64, а длинный - 64.

Эти предположения - отличная идея, но вас не уволят за их создание.

В теории, <stdint.h> можно использовать для указания типов фиксированной битовой ширины, но вам нужно подстроить один для Microsoft. (См. здесь для MS stdint.h.) Одна из проблем здесь заключается в том, что на С++ техническая совместимость C89 должна быть только совместимой; даже для простых C, C99 не полностью поддерживается даже в 2009 году.

Также неточно сказать, что для char нет спецификации ширины. Существует, стандарт просто избегает говорить, подписан ли он или нет. Вот что говорит C99:

  • количество бит для наименьшего объекта, который не является битовым полем (байт)
    CHAR_BIT 8
  • минимальное значение для объекта типа, подписанного char
    SCHAR_MIN -127//- (2 7 - 1)
  • максимальное значение для объекта типа, подписанного char
    SCHAR_MAX +127//2 7 - 1
  • максимальное значение для объекта типа unsigned char
    UCHAR_MAX 255//2 8 - 1

Ответ 7

Большинство библиотек определяют что-то вроде этого:

#ifdef MY_ARCHITECTURE_1
typedef unsigned char u_int8_t;
typedef short int16_t;
typedef unsigned short u_int16_t;
typedef int int32_t;
typedef unsigned int u_int32_t;
typedef unsigned char u_char;
typedef unsigned int u_int;
typedef unsigned long u_long;
typedef unsigned short u_short;
#endif

вы можете использовать эти typedef в своих программах вместо стандартных типов.

Ответ 8

C99 N1256 стандартная черновик

C99 определяет два типа целочисленных гарантий:

  • гарантии минимального размера
  • относительные размеры между типами

Относительные гарантии

6.2.5 Типы:

8 Для любых двух целых типов с одинаковой степенью соответствия и разного целочисленного преобразования (см. 6.3.1.1), диапазон значений типа с меньшим целым числом ранга преобразования равен поддиапазон значений другого типа.

и 6.3.1.1 Булевы, символы и целые числа определяют относительные числа рангов:

1 Каждый целочисленный тип имеет целочисленный ранг преобразования, определяемый следующим образом:

  • Ранг long long int должен быть больше ранга long int, который должен быть больше ранга int, который должен быть больше ранга короткого int, который должен быть больше ранга подписанного char.
  • Ранг любого беззнакового целочисленного типа должен быть равен рангам соответствующего значный целочисленный тип, если он есть.
  • Для всех целых типов T1, T2 и T3, если T1 имеет больший ранг, чем T2, а T2 имеет больший ранг, чем T3, то T1 имеет больший ранг, чем T3

Абсолютные минимальные размеры

Упомянутый fooobar.com/info/73346/..., вот цитата для удобства.

5.2.4.2.1 Размеры целых типов <limits.h>:

1 [...] Их значения, определяемые реализацией, должны быть равны или больше по величине (по абсолютной величине) показанным [...]

  • UCHAR_MAX 255//2 8 - 1
  • USHRT_MAX 65535//2 16 - 1
  • UINT_MAX 65535//2 16 - 1
  • ULONG_MAX 4294967295//2 32 - 1
  • ULLONG_MAX 18446744073709551615//2 64 - 1

Плавающая точка

Если макрос __STDC_IEC_559__ определен, то для каждого типа C гарантируются типы IEEE: Можно ли предположить, что с плавающей запятой представляется с использованием поплавков IEEE754 в C?