Всегда ли C99 требует, чтобы тип int64_t был доступен?

Требует ли стандарт C99, чтобы соответствующий компилятор имел 64-битный int64_t определенный (и пригодный для использования)? Или он необязателен и определяется всеми популярными компиляторами? Я, очевидно, спрашиваю конкретно о платформах, на которых ЦП не может напрямую обрабатывать 64-битные значения, но вопрос более общий.

Я не могу понять это ни из Страница Википедии типов данных C, ни из этот ответ на связанный вопрос.

Не уверен насчет C99, но int64_t определенно необязателен в C11, за исключением случаев, когда это не так. Подробности см. в разделе 7.20.1.1 спецификации C11.

user3386109 27.02.2019 23:57

@ user3386109: Могу я вас попросить ссылку? Кроме того, ваша формулировка довольно загадочна.

einpoklum 27.02.2019 23:59

Извините, у меня нет ссылки. Но проект спецификации C11 находится в свободном доступе в Интернете, и его можно найти, выполнив поиск N1570

user3386109 28.02.2019 00:01
Ссылка на проект C11. Типы необязательны, но должны быть предоставлены, если архитектура машины имеет соответствующий тип, и должны быть предоставлены, если некоторый целочисленный тип имеет такие же характеристики.
rici 28.02.2019 00:03

В любом случае ответ "нет". Вы не можете рассчитывать на существующие типы.

rici 28.02.2019 00:08

@phuclv: Все это просто не то, о чем я просил.

einpoklum 01.03.2019 01:23

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

phuclv 01.03.2019 02:34
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
9
222
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Нет, C99 не требует типа int64_t.

(Спасибо @user3386109, @Clifford)

Доступность типа int64_t не требуется. Цитируя Стандартный проект документа C99 N1256:

7.18.11.1 Exact-width integer types

  1. The typedef name int N_t designates a signed integer type etc. etc. ...
  2. 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 бит.

Использование слова «вероятно» не звучит как однозначный ответ.

machine_1 28.02.2019 00:11

Юу мог бы так же легко сослаться на черновик C99 и быть категоричным. open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf

Clifford 28.02.2019 00:26

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.. GitHub STOP HELPING ICE 28.02.2019 00:24

@R.. Согласитесь, что «C не требует, чтобы long long был 64-битным», поэтому в ответе есть «long long, который находится в наименее 64-битном». Может быть шире. Он может иметь такой узкий диапазон, как [-0x7fff-ffff-ffff-ffff ... +0x7fff-ffff-ffff-ffff]

chux - Reinstate Monica 28.02.2019 00:32

Он даже не требует, чтобы он был «не менее 64 бит». для этого требуется, чтобы он был не менее 63,999999999999999999921... бит. Извините, мой первый комментарий был неправильно сформулирован и в нем отсутствовала фраза «по крайней мере», но дело в том, что «по крайней мере» ложно из-за обратных положений, разрешающих реализации с дополнением до единицы, знаком/величиной и «недостаточным дополнением до двух».

R.. GitHub STOP HELPING ICE 28.02.2019 00:33

@R.. Поскольку дробных бит не существует, это то же самое, что «не менее 64 бит».

Barmar 28.02.2019 00:35

@Barmar: Нет, вам нужно округлить в меньшую сторону, если вы хотите подсчитывать только целые биты, и в этом случае он фактически 63-битный (т. Е. Самый большой интервал степени двойки, который полностью представлен в диапазоне, составляет 2 ^ 63 в длину, не 2^64). Один из способов думать об этом состоит в том, что один бит потенциально «не полностью пригоден для использования».

R.. GitHub STOP HELPING ICE 28.02.2019 00:36

@R.. Типы со знаком ограничены общим два дополнения. Редкое дополнительное кодирование знак и величина и дополнение также требует минимального 64-битного кодирования. Конечно, мы разделяем волосы / биты. ;-)

chux - Reinstate Monica 28.02.2019 00:37

Обратите внимание, что следующая версия стандарта C исправит это, предписав полное дополнение до двух для всех целочисленных типов. Мы должны поблагодарить за это JF Bastien из SO! :-)

R.. GitHub STOP HELPING ICE 28.02.2019 00:38

@R.. Если вам требуется не менее 63,9999... бит, и вы округляете в меньшую сторону, у вас будет меньше битов, и вы не сможете закодировать весь диапазон.

Barmar 28.02.2019 00:39

@R.. Интересные новости о следующей версии C. Есть ожидаемый год?

chux - Reinstate Monica 28.02.2019 00:39

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

0___________ 28.02.2019 00:40

@Barmar: Дело в том, что вы не можете представить полный 64-битный диапазон в такой реализации, поэтому, если вы хотите рассматривать long long как имеющий диапазон степени двойки, вы должны рассматривать его только как 63-битный. Конечно, вы можете рассматривать его как имеющий полный почти 64-битный диапазон, но это не 64-битный диапазон, и неправильно описывать его как таковой.

R.. GitHub STOP HELPING ICE 28.02.2019 00:40

@chux: Кажется, я где-то видел оценку, но не помню, где. Тем не менее, я время от времени связывался с jfbastien через Twitter и другие каналы по поводу предложения и его принятия.

R.. GitHub STOP HELPING ICE 28.02.2019 00:42

@R.. Я хочу сказать, сколько бит вам нужно для представления требуемого диапазона. Представление знак/величина не может представлять тот же диапазон, что и 64-битное дополнение до двух, но для представления этого диапазона все равно требуется 64 бита (63 бита величины, 1 бит знака).

Barmar 28.02.2019 00:44

@Barmar: Обычно при использовании типа вас волнует диапазон значений, которые он может представлять, а не (или, по крайней мере, больше) объем памяти, который ему требуется. Если вы говорите о хранении, вы также должны учитывать биты заполнения.

R.. GitHub STOP HELPING ICE 28.02.2019 00:47

@Р.. Конечно. Но вы были тем, кто сказал, что «требуется не менее 63,9999999999999999999921... бит», что, похоже, говорит об объеме памяти.

Barmar 28.02.2019 00:49

@Barmar: Скорее речь идет о пространстве возможных значений. Дробные биты имеют смысл, когда речь идет об энтропии/возможностях.

R.. GitHub STOP HELPING ICE 28.02.2019 01:19

Существует три набора целочисленные типы:

  • 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. У некоторых стандартных фанатиков случился бы сердечный приступ - не будет возможности написать переносимый код для машин с ферритовой памятью. Конец мира. Жизнь будет бессмысленной.
0___________ 28.02.2019 00:31

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

Jonathan Leffler 28.02.2019 00:35

Также есть машины класса DSP с CHAR_BIT из 16. У них есть проблемы с int8_t, но не с другими типами.

Jonathan Leffler 28.02.2019 00:41

Обратите внимание, что хотя int_least64_t обязан существовать, его диапазон не обязательно должен быть как минимум таким же большим, как int64_t, если бы он существовал. int_least64_t разрешено снижаться только до -2 ^ 63 + 1, а не до -2 ^ 63. Это будет исправлено в следующей редакции стандарта C. См. 7.20.2.2 Ограничения целочисленных типов минимальной ширины.

R.. GitHub STOP HELPING ICE 28.02.2019 00:43

@JonathanLeffler никто не пишет для них переносимый код. Если кто-то попытается использовать на них uint8_t, следует найти более легкую работу.

0___________ 28.02.2019 00:53
Ответ принят как подходящий

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 28.02.2019 09:33

Да, @einpoklum, в принципе можно. Как я уже сказал, «соответствующая реализация не обязана предоставлять какой-либо тип, который точно соответствует характеристикам int64_t, а если это не так, то она не должна (действительно, не должна [...]) предоставлять тип int64_t ". Однако на практике я не знаю ни одной существующей реализации, соответствующей C99 или C11, которая не обеспечивает int64_t.

John Bollinger 28.02.2019 15:13

Другие вопросы по теме