Требует ли стандарт C99, чтобы соответствующий компилятор имел 64-битный int64_t определенный (и пригодный для использования)? Или он необязателен и определяется всеми популярными компиляторами? Я, очевидно, спрашиваю конкретно о платформах, на которых ЦП не может напрямую обрабатывать 64-битные значения, но вопрос более общий.
Я не могу понять это ни из Страница Википедии типов данных C, ни из этот ответ на связанный вопрос.
@ user3386109: Могу я вас попросить ссылку? Кроме того, ваша формулировка довольно загадочна.
Извините, у меня нет ссылки. Но проект спецификации C11 находится в свободном доступе в Интернете, и его можно найти, выполнив поиск N1570
В любом случае ответ "нет". Вы не можете рассчитывать на существующие типы.
Возможный дубликат Общие сведения о целочисленных типах фиксированной ширины
@phuclv: Все это просто не то, о чем я просил.
Определенно да. Все они говорят, что целые числа фиксированной ширины не требуются в системах, которые их не поддерживают. Требуется только вариант least





int64_t.(Спасибо @user3386109, @Clifford)
Доступность типа int64_t не требуется. Цитируя Стандартный проект документа C99 N1256:
7.18.11.1 Exact-width integer types
- The typedef name int N_t designates a signed integer type etc. etc. ...
- These types are optional. However, if an implementation provides integer types with widths of ... 64 bits... that have a two’s complement representation... it shall define the corresponding typedef name.
Но посмотрите ответы @chux и @JohnBollinger о long long наличии 64 бит.
Использование слова «вероятно» не звучит как однозначный ответ.
Юу мог бы так же легко сослаться на черновик C99 и быть категоричным. open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
Does the C99 standard mandate that a conforming compiler have a 64-bit int64_t defined (and usable)?
Нет, но для C99 требуется long long, который имеет 64-битное значение наименее.
Кроме того, int64_t очень широко доступен. Маловероятно, что вы встретите совместимый C99 без int64_t, так как он требуется почти на всех платформах.
C11dr 7.20.1.1 Exact-width integer types
(int64_t) .... if an implementation provides integer types with widths of 8, 16, 32, or 64 bits, no padding bits, and (for the signed types) that have a two’s complement representation, it shall define the corresponding typedef names.
Разрядность процессора не влияет на эту функциональность — long long должен существовать. Если этот long long (или любой стандартный тип является 64-битным дополнением 2), то int64_tдолжен тоже существует. Разрядность процессора влияет на представление.
Комментарий @Р.. подчеркивает, что long long, для кодирования которого требуется 64 бита памяти, по спецификации может поддерживать только диапазон [-0x7fff-ffff-ffff-ffff ... +0x7fff-ffff-ffff-ffff], один меньше int64_t диапазон [-0x8000-0000-0000-0000 ... +0x7fff-ffff-ffff-ffff]. Такие платформы в наши дни крайне редки, если они вообще существуют.
C не требует, чтобы long long был 64-битным. LLONG_MIN разрешено быть -0x7fffffffffffffff, что делает его почти на 100 зептобит меньше 64-битного, если реализация делает такой плохой выбор (и, для практических целей, 63-битный).
@R.. Согласитесь, что «C не требует, чтобы long long был 64-битным», поэтому в ответе есть «long long, который находится в наименее 64-битном». Может быть шире. Он может иметь такой узкий диапазон, как [-0x7fff-ffff-ffff-ffff ... +0x7fff-ffff-ffff-ffff]
Он даже не требует, чтобы он был «не менее 64 бит». для этого требуется, чтобы он был не менее 63,999999999999999999921... бит. Извините, мой первый комментарий был неправильно сформулирован и в нем отсутствовала фраза «по крайней мере», но дело в том, что «по крайней мере» ложно из-за обратных положений, разрешающих реализации с дополнением до единицы, знаком/величиной и «недостаточным дополнением до двух».
@R.. Поскольку дробных бит не существует, это то же самое, что «не менее 64 бит».
@Barmar: Нет, вам нужно округлить в меньшую сторону, если вы хотите подсчитывать только целые биты, и в этом случае он фактически 63-битный (т. Е. Самый большой интервал степени двойки, который полностью представлен в диапазоне, составляет 2 ^ 63 в длину, не 2^64). Один из способов думать об этом состоит в том, что один бит потенциально «не полностью пригоден для использования».
@R.. Типы со знаком ограничены общим два дополнения. Редкое дополнительное кодирование знак и величина и дополнение также требует минимального 64-битного кодирования. Конечно, мы разделяем волосы / биты. ;-)
Обратите внимание, что следующая версия стандарта C исправит это, предписав полное дополнение до двух для всех целочисленных типов. Мы должны поблагодарить за это JF Bastien из SO! :-)
@R.. Если вам требуется не менее 63,9999... бит, и вы округляете в меньшую сторону, у вас будет меньше битов, и вы не сможете закодировать весь диапазон.
@R.. Интересные новости о следующей версии C. Есть ожидаемый год?
Я думаю, что он будет больше сосредоточен на очень важных вопросах, таких как триграфы и так далее. Любая попытка модернизации будет противодействовать IBM (как всегда), поскольку они создали 60 лет назад странные архитектуры и хотят, чтобы на них можно было реализовать стандарт C.
@Barmar: Дело в том, что вы не можете представить полный 64-битный диапазон в такой реализации, поэтому, если вы хотите рассматривать long long как имеющий диапазон степени двойки, вы должны рассматривать его только как 63-битный. Конечно, вы можете рассматривать его как имеющий полный почти 64-битный диапазон, но это не 64-битный диапазон, и неправильно описывать его как таковой.
@chux: Кажется, я где-то видел оценку, но не помню, где. Тем не менее, я время от времени связывался с jfbastien через Twitter и другие каналы по поводу предложения и его принятия.
@R.. Я хочу сказать, сколько бит вам нужно для представления требуемого диапазона. Представление знак/величина не может представлять тот же диапазон, что и 64-битное дополнение до двух, но для представления этого диапазона все равно требуется 64 бита (63 бита величины, 1 бит знака).
@Barmar: Обычно при использовании типа вас волнует диапазон значений, которые он может представлять, а не (или, по крайней мере, больше) объем памяти, который ему требуется. Если вы говорите о хранении, вы также должны учитывать биты заполнения.
@Р.. Конечно. Но вы были тем, кто сказал, что «требуется не менее 63,9999999999999999999921... бит», что, похоже, говорит об объеме памяти.
@Barmar: Скорее речь идет о пространстве возможных значений. Дробные биты имеют смысл, когда речь идет об энтропии/возможностях.
Существует три набора целочисленные типы:
intN_t — такие как int64_t и их беззнаковые аналоги; эти точные типы могут быть недоступны.int_leastN_t — например, int_least64_t; типы int_least8_t, int_least16_t, int_least32_t и int_least64_t и их беззнаковые аналоги являются обязательными — другие типы являются необязательными.int_fastN_t — например, int_fast64_t; требуются типы int_fast8_t, int_fast16_t, int_fast32_t и int_fast64_t (это самый быстрый тип, по крайней мере, с заданной шириной).Стандарт также требует поддержки long long, а минимальный допустимый диапазон для long long требует не менее 64 бит (см. §5.2.4.1 Размеры целочисленных типов <limits.h>). Следовательно, стандарт может законно требовать поддержки «наименее» и «быстрых» типов на 64 битах и более — это также требуется для поддержки long long.
Раньше были компьютеры с 36-битными словами и другие с 60-битными словами. Оба они будут изо всех сил пытаться предоставить (в основном, «не могут предоставить») точные типы ширины, но могут легко обеспечить поддержку «наименее» и «быстрых» типов.
Стандарт не предписывает «точные типы ширины» — см. §7.20.1.1 Целочисленные типы точной ширины ¶3:
These types are optional. However, if an implementation provides integer types with widths of 8, 16, 32, or 64 bits, no padding bits, and (for the signed types) that have a two's complement representation, it shall define the corresponding typedef names.
There used to be computers with 36-bit words, and others with 60-bit words. Новый стандарт должен забыть о компьютерах 40-50-летней давности. И да, для них не будет соответствующих компиляторов C21. У некоторых стандартных фанатиков случился бы сердечный приступ - не будет возможности написать переносимый код для машин с ферритовой памятью. Конец мира. Жизнь будет бессмысленной.
То, что было мало актуально двадцать лет назад, сейчас уже не так актуально. В 1999 году по крайней мере несколько машин такого типа все еще работали за пределами компьютерных музеев. В наши дни не так уж и много.
Также есть машины класса DSP с CHAR_BIT из 16. У них есть проблемы с int8_t, но не с другими типами.
Обратите внимание, что хотя int_least64_t обязан существовать, его диапазон не обязательно должен быть как минимум таким же большим, как int64_t, если бы он существовал. int_least64_t разрешено снижаться только до -2 ^ 63 + 1, а не до -2 ^ 63. Это будет исправлено в следующей редакции стандарта C. См. 7.20.2.2 Ограничения целочисленных типов минимальной ширины.
@JonathanLeffler никто не пишет для них переносимый код. Если кто-то попытается использовать на них uint8_t, следует найти более легкую работу.
Does the C99 standard mandate that a conforming compiler have a 64-bit int64_t defined (and usable)? Or is it optional, and just happens to be defined by all popular compilers?
Тип является необязательным в одном смысле и условно обязательным в другом смысле. В частности, C99 говорит,
The typedef name intN_t designates a signed integer type with width N , no padding bits, and a two's complement representation. [...]
These types are optional. However, if an implementation provides integer types with widths of 8, 16, 32, or 64 bits, no padding bits, and (for the signed types) that have a two's complement representation, it shall define the corresponding typedef names.
Таким образом, int64_t является необязательным в том смысле, что соответствующая реализация не обязана предоставлять какой-либо тип, который точно соответствует характеристикам int64_t, а если нет, то и не нужно (действительно, не должно, согласно другому разделу ) укажите тип int64_t.
C99 указывает, что существует тип long long int, требуемый минимальный диапазон которого требует представления шириной не менее 64 бит. Теперь возможно, что в какой-то реализации нет целочисленного типа со знаком точно шириной 64 бита (например, может быть int 24 бита, long 48 и long long 96), и возможно, что есть 64-значное целое число тип, но он содержит биты заполнения или не представлен в дополнении до двух. Такие реализации могут быть полностью соответствующими, но не определять int64_t. На практике, однако, сегодня не существует таких широко используемых реализаций.
Итак, может ли у вас быть компилятор, совместимый с C99, который не предоставляет int64_t? Я имею в виду, может ли, скажем, long long иметь размер, не равный степени двойки, или 128 бит, а int64_t отсутствовать?
Да, @einpoklum, в принципе можно. Как я уже сказал, «соответствующая реализация не обязана предоставлять какой-либо тип, который точно соответствует характеристикам int64_t, а если это не так, то она не должна (действительно, не должна [...]) предоставлять тип int64_t ". Однако на практике я не знаю ни одной существующей реализации, соответствующей C99 или C11, которая не обеспечивает int64_t.
Не уверен насчет C99, но
int64_tопределенно необязателен в C11, за исключением случаев, когда это не так. Подробности см. в разделе 7.20.1.1 спецификации C11.