2009-10-23 2 views
9

Я знаю, что спецификация языка C не определяет точный размер каждого целочисленного типа (например, int).Размер int в C на разных архитектурах

Что мне интересно: есть ли способ в C (а не C++) определить целочисленный тип с определенным размером, который гарантирует, что он будет одинаковым для разных архитектур? Нравится:

typedef int8 <an integer with 8 bits> 
typedef int16 <an integer with 16 bits> 

Или любым другим способом, который позволит скомпилировать другие части программы по разной архитектуре.

+1

Ваш вопрос очень похож на http://stackoverflow.com/questions/126279/c99-stdint-h-header-and-ms-visual-studio –

+2

@zilgo: ответ может быть аналогичным; вопрос не является. В 126279 OP уже знает stdint.h; NawaMan (по-видимому) не был, задавая вопрос. –

+2

Обратите внимание, что последнее предположение неверно. Различия в размере int не обязательно блокируют компиляцию на других архитектурах, но скрытые предположения, такие как 'i == i & 0xFFFFFFFF', могут. Хороший программист пишет '& 0xFFFF', когда ему нужен математический modulo 2^16, и ему все равно, имеет ли' unsigned short' ровно 16 бит. – MSalters

ответ

15

Что вы хотите <stdint.h>, что компиляторы, соответствующие стандарту C («C99») будет осуществлять , К сожалению, это не относится к Microsoft. К счастью, проект с открытым исходным кодом предоставляет <stdint.h> для Windows, см. msinttypes.

Это позволит вам использовать int32_t и uint32_t, а также 8, 16 и 64 и многие другие.

Примечание: сам файл заголовка не является обязательным в стандарте, однако большинство типов в заголовке являются индивидуально необязательными. Некоторые - нет. Наиболее часто используемые типы являются необязательными, но ничто не мешает вам использовать нужные. Дело в том, что если реализация обеспечивает заголовок вообще, на практике они определяют все типы.

+0

Означает ли это, что если я всегда компилирую свой код с компилятором C99 и всегда включаю , я должен быть уверен, что int32_t всегда 4 байта? – NawaMan

+0

@NawaMan - вы можете быть уверены, что 'int32_t' будет иметь ровно 32 бита. Если платформа не имеет 32-битного типа int, компиляция завершится неудачно, поскольку тип 'int32_t' не будет определен. Кроме того, многие компиляторы, отличные от C99, предоставляют «stdint.h» - для тех, кто этого не делает (Microsoft), вы можете получить один из нескольких мест, указанных в других комментариях/ответах, в том числе: http://snipplr.com/view/ 18199/stdinth/ –

+0

@NawaMan: ДА. Следует также отметить, что C99 дает минимальные значения для классических типов: int> = 16, long> = 32, long long> = 64. – DigitalRoss

13

C99, в stdint.h, определяет такие типы, как int8_t и int16_t.

+0

Я считаю, что есть версия, которая охватывает многие другие платформы, которые также не соответствуют C99, но я не уверен. –

+0

MSVC не любит ''. Не то, чтобы меня это волнует, я прекратил использовать его из-за ужасного кода. – LiraNuna

+0

Это интересно. Вы говорите, что у него нет stdint.h или cstdint или что у него нет int16_t, хотя он поддерживает тип с такой шириной бита? Это, я думаю, сделает его несоответствующим, и я сомневаюсь, что MS будет такой глупой. – paxdiablo

2

Если вы не проверяете каждую платформу #ifdef или около того, я сомневаюсь, что это возможно. Но многие библиотеки уже выполняют эту задачу для вас. Для MSVC это __int8, __int16, &c.. Библиотека GTK имеет аналогичные typedef.

2

Насколько я знаю, ответ отрицательный. Мы кодируем для разных платформ, и мы просто используем typedef для определенных платформ, используя # if/# else. Например, в Win32: typedef int int32;

С уважением,

Sebastiaan

5

Нет, стандарт C определяет минимальные размеры для целочисленных типов, но не дает никакой гарантии на максимальных размерах.

Реализация должна обеспечивать типы intN_t, если имеются типы такого размера. Я только упоминаю, что, поскольку у вас есть кросс-платформенный тег - реализация, которая не имеет типа правильной ширины бита, не должна предоставлять эти типы.

Обычно вы можете выбрать (с настройкой, определяющей, например, cc -D_INT16_IS_INT и #ifdef s) правильный тип для использования для определенного размера бит. Вы можете разработать необходимые определения для каждой платформы, которую вы хотите поддерживать с помощью кода C, используя CHAR_BIT и sizeof().

Соответствующий раздел проекта C1X (n1362) составляет:


7.18.1.1 Точных ширина целочисленных типов

  1. Названия ЬурейеГо intN_t обозначает целочисленный тип с ширина N, без битов дополнений и представления двух дополнений. Таким образом, int8_t обозначает знаковый целочисленный тип с шириной ровно 8 бит.

  2. Имя typedef uintN_t обозначает целочисленный тип без знака с шириной N. Таким образом, uint24_t обозначает целочисленный тип без знака с шириной ровно 24 бита.

  3. Эти типы являются необязательными. Однако, если реализация предоставляет целочисленные типы с шириной 8, 16, 32 или 64 бита, без битов дополнений и (для подписанных типов), которые имеют представление двух дополнений, оно должно определять соответствующие имена typedef.


Что касается выбора типов, что-то вроде этого должно хватить:

#ifdef INT32_IS_SHORT 
    typedef short INT32 
#endif 
#ifdef INT32_IS_INT 
    typedef int INT32 
#endif 
#ifdef INT32_IS_LONG 
    typedef long INT32 
#endif 
+2

Если вы хотите выйти из строя, когда система не имеет точного размера, просто используйте 'int8_t' или' int16_t' - сборка завершится неудачно, если система не будет иметь их - нет необходимости в условном коде. Если вы хотите не сбой, но вместо этого используйте следующий лучший тип, используйте int_least8_t или int_least16_t. –

+1

Препроцессор не может оценить 'sizeof()'. –

+0

Согласно стандарту C99, длинный должен быть более 16 бит;) –

0

Вы всегда можете написать арифметическую библиотеку, которая использовала векторы unsigned char для чисел. Таким образом, вы можете использовать числа любой длины бит, которые вы хотите, и даже допускать изменение длины бит.

На самом деле вам не нужно реализовывать такую ​​библиотеку, потому что GNU MP обрабатывает это уже.

http://gmplib.org/

2

Вы можете взглянуть на pstdint.h. Это переносимая реализация stdint.h и не требует поддержки компилятора C99.

Смежные вопросы