Почему типы фиксированной ширины делегируются примитивам?

В Visual Studio 14 stdint.h В заголовке есть определения для целочисленных типов фиксированной ширины, но если вы действительно посмотрите на определения, они просто делегируют обратно примитивам. Определения следующие:

typedef signed char        int8_t;
typedef short              int16_t;
typedef int                int32_t;
typedef long long          int64_t;
typedef unsigned char      uint8_t;
typedef unsigned short     uint16_t;
typedef unsigned int       uint32_t;
typedef unsigned long long uint64_t;

Так есть ли основания использовать stdint.h если все, что он делает, это просто откат к примитивам? Я также знаю, что Visual Studio не просто заменяет эти определения во время компиляции, потому что если вы попытаетесь распечатать int8_t на консоли вы получите символ Unicode вместо числа, потому что это на самом деле просто signed char,

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

Почему заголовок, который в спецификации C ++ гласит, что он будет иметь целые числа фиксированной длины 8, 16, 32 и 64 бита, определяет эти целые числа как типы, которые по определению могут быть любого размера, который компилятор хочет (поместить в как сказал кто-то другой в другом вопросе The compiler can decide that an int will a 71 bit number stored in a 128 bit memory space where the additional 57 bits are used to store the programmers girlfriends birthday.)?

0

Решение

Как из первоначальных, так и из повторных вопросов я понимаю, что существует неправильное представление о целых числах с гарантированной шириной (и я говорю гарантированно, потому что не все типы в stdint.h имеют фиксированную ширину) и реальные проблемы, которые они решают.

C / C ++ определяют примитивы, такие как int, long int, long long int и т.д. Для простоты давайте сосредоточимся на наиболее распространенных из всех, то есть int, Что определяет стандарт С, так это то, что int должен иметь ширину не менее 16 бит. Хотя компиляторы на всех широко используемых платформах x86 на самом деле предоставят вам 32-битное целое число, когда вы определите int, Это происходит потому, что процессоры x86 могут напрямую извлекать 32-разрядное поле (размер слова 32-разрядного процессора x86) из памяти, предоставлять его в виде ALU для 32-разрядной арифметики и сохранять его обратно в память без необходимости выполнять какие-либо действия. сдвиги, отступы и т. д., и это довольно быстро. Но это не так для каждой комбинации компилятор / архитектура. Если вы работаете на встроенном устройстве, например, с очень маленьким процессором MIPS, вы, вероятно, получите 16-битное целое число от компилятора при определении int, Таким образом, ширина примитивов определяется компилятором в зависимости исключительно от аппаратных возможностей целевой платформы по отношению к минимальной ширине, определенной стандартом. И да, на странной архитектуре, например, с 25-битный ALU, вам, вероятно, дадут 25-битный int,

Для того, чтобы фрагмент кода C / C ++ был переносимым среди множества различных комбинаций компилятор / аппаратное обеспечение, stdint.h предоставляет typedefs, которые гарантируют вам определенную ширину (или минимальную ширину). Так, например, когда вы хотите использовать 16-разрядное целое число со знаком (например, для экономии памяти или счетчиков модов), вам не нужно беспокоиться о том, следует ли использовать int или же short, просто используя int16_t, Разработчики компилятора предоставят вам правильно сконструированные stdint.h это определит запрошенное целое число фиксированного размера в фактическом примитиве, который его реализует. Это означает, что на x86 int16_t вероятно будет определяться как shortв то время как на небольшом встроенном устройстве вы можете получить intсо всеми этими отображениями, поддерживаемыми разработчиками компилятора.

1

Другие решения

Различные платформы определяют примитивы по-разному. На одной платформе int может быть 16-битным, в то время как для другого 32-битным. Если вы строго зависите от переменной, имеющей определенную ширину, вы должны использовать типы в stdint.h, который всегда будет typedefПравильно, чтобы их соответствующие примитивы на текущей платформе.

4

Так есть ли причина использовать stdint.h, если все, что он делает, это просто откат к примитивам?

Что еще это будет делать?

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

Этот заголовок просто дает вам удобные, стандартные, гарантированно согласованные псевдонимы.

3

В ответ на вновь сформулированный вопрос, это не компилятор, делающий выбор, чтобы сохранить день рождения в старших 57 битах. Это был разработчик. Компилятор не может использовать любую битовую глубину для целочисленного типа. Он будет использовать любую битовую глубину, указанную разработчиками компилятора, и разработчики выберут эти битовые глубины в соответствии с требования стандарта C ++. Как только компилятор настроен и скомпилирован, глубина в битах не изменится1. Эти 71 бит будут гарантированы, пока вы не измените компиляторы или версии компиляторов.

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

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

0
По вопросам рекламы [email protected]