Гарантируется ли, что типы с явным указанием размера (такие, как uint32_t, uint64_t, uint16_t) занимают одинаковое количество памяти на всех платформах (на десктопах, на мобилах, на микроконтроллерах)? Собственно, независимо от ответа, как эти типы можно использовать, есть ли какие-нибудь особенные задачи, где очень нужно знать размер в битах? Маски, флаги? Верно ли то, что в современном C обычный деревянный int под неким табу и не стоит использовать типы, размер которых меняется от платформы к платформе (здесь важны ссылки на стандарт, если он каким-то образом это регулирует или на мануалы к компилятору)?
- 6,449
-
2Похожий вопрос. – αλεχολυτ Feb 14 '17 at 12:00
-
2Возможный дубликат вопроса: cstdint правильное использование – free_ze Feb 14 '17 at 12:07
4 Answers
типы с явным указанием размера
Стандарт гарантирует их размеры, но не их существование. Т. е. теоретически можно встретить платформу, на которой нет нужного типа. Зато если уж программа скомпилировалась, то размер типа ты точно знаешь.
Там ещё есть типы со словом least, например, uint_least32_t, если тебе надо хотя бы 32 бита.
обычный деревянный int
Стандарт не гарантирует его размер.
не стоит использовать типы, размер которых меняется от платформы к платформе
Всё зависит от задач. Если мне нужна 32-битная маска для перебора, то логично не полагаться на int. Если какой-то размер, то есть size_t, зависящий от битности программы. А если мне нужно вывести число процентов, то можно и обычный int взять.
- 123,725
Типы вида intN_t или uintN_t обязаны иметь размер в битах, в точности совпадающий с N. Об этом написано в Стандарте языка (пример для intN_t):
7.20.1.1 Exact-width integer types
1 The typedef nameintN_tdesignates a signed integer type with widthN, no padding bits, and a two’s complement representation. Thus,int8_tdenotes such a signed integer type with a width of exactly8bits.
Точный размер типов нужен при взаимодействии разных компонентов системы, которые могут работать на различных платформах. Т.к. sizeof(int) не регламентирован стандартом, его нельзя безопасно использовать в таких случаях. Но если переменная этого типа не выходит за границы одной системы, то разумнее опираться именно на базовые типы, вроде int.
Дополнительную информацию можно почерпнуть в похожем вопросе по c++.
- 28,987
- 13
- 60
- 119
Отвечаю на вопрос "зачем нужны типы фиксированного размера?"
Во-первых, для передачи структур данных по сети.
Висят 2 программы (с одинаковым исходным кодом, но каждая скомпилирована на месте) на двух разных системах и общаются сообщениями. Пусть, каждое сообщение состоит из 10 чисел по 4 байта. Но одна система 32 бита, а вторая - 64. Используете int? Флаг в руки. Всё сломается по очевидным причинам.
Во-вторых, для работы с различными форматами.
Картинки, архивы, видео, бинарные конфиги различных программ имеют фиксированные структуры. И если там какое-то поле является беззнаковым целым размером 4 байта, то нужно использовать платформонезависимые типы.
Примеров можно привести много :)
- 2,465
-
4
-
-
3Эм.. передача по сети без специальной сериализации всё равно поломается, если встретятся big и little indian. С форматами файлов - так же. А ещё, по факту int сейчас везде int32, хотя этого никто и не обещал. – Qwertiy Feb 14 '17 at 12:16
-
@Qwertiy специальная сериализация, конечно, поможет на этапе компиляции словить предупреждение. Но пример-то нужно было придумать. Возможно, с int пример не лучший, а вот какой-нибудь size_t очень даже годится – int3 Feb 14 '17 at 12:19
-
1Ага, сейчас! size_t -- архитектурно зависимый тип. Его размер меняется. @Qwerty Прелестная опечатка, бедные индейцы! (Ну и это, вы давно за микроконтроллеры садились? int в эквиваленте разрядности uint16_t -- довольно распространённая штука.) – 0andriy Feb 15 '17 at 23:19
-
2@0andriy я как раз имел в виду, что size_t годится для примера, где разные платформы, поэтому нужно использовать платформонезависимые типы. – int3 Feb 16 '17 at 05:23
-
@0andriy, если будешь писать ник с ошибкой, то сообщение прочитают случайно через два с половиной года ;) – Qwertiy Dec 21 '19 at 22:16
-
@0andriy, так вроде суть того комментария и была про то, что если использовать архитектурнозависимый тип, то вероятность, что что-то развалится больше. Впрочем, сейчас long - отличный кандидат на x64 - он зависит от ОС - на винде 4, а в линуксе 8)) – Qwertiy Dec 21 '19 at 22:18
Размер int может быть разным на разных платформах и может также зависеть от разных компиляторов. А при использовании того же uint32_t точно известно сколько он занимает. Еще встречалась такая ситуация что Int не хватало. А использование вещественных типов не допускается. Приходилось использовать uint32_t.