Согласно C и C ++, CHAR_BIT >= 8
,
Но всякий раз, когда CHAR_BIT > 8
, uint8_t
даже не может быть представлен как 8 бит.
Это должно быть больше, потому что CHAR_BIT
минимальное количество бит для любого типа данных в системе.
На какую систему можно uint8_t
быть юридически определенным как тип, отличный от unsigned char
?
(Если ответ для C и C ++ разный, то я хотел бы знать оба.)
Если он существует, uint8_t
должна всегда иметь ту же ширину, что и unsigned char
, Однако это не обязательно должен быть тот же тип; это может быть отдельный расширенный целочисленный тип. Это также не должно иметь такое же представление, как unsigned char
; например, биты могут быть интерпретированы в обратном порядке. Это глупый пример, но он имеет больше смысла для int8_t
, где signed char
может быть дополнением или знаком int8_t
должен быть дополнением до двух.
Еще одно «преимущество» использования расширенного целочисленного типа, не являющегося символом, для uint8_t
даже на «нормальных» системах есть правила псевдонимов Си. Символьным типам разрешено псевдонимом чего угодно, что не позволяет компилятору сильно оптимизировать функции, которые используют как символьные указатели, так и указатели на другие типы, если только restrict
Ключевое слово было применено хорошо. Однако, даже если uint8_t
имеет точно такой же размер и представление, как unsigned char
если реализация сделала его отличным, не символьным типом, правила псевдонимов не будут применяться к нему, и компилятор может предположить, что объекты типов uint8_t
а также int
Например, никогда не может псевдоним.
На какую систему можно
uint8_t
быть юридически определенным как тип, отличный отunsigned char
?
В итоге, uint8_t
может быть юридически определено только в тех системах, где CHAR_BIT
равно 8. Это адресуемая единица с ровно 8 битами значения и без битов заполнения.
В деталях, CHAR_BIT
определяет ширину наименьших адресуемых блоков и uint8_t
не может иметь битов заполнения; он может существовать только в том случае, если наименьшая адресуемая единица имеет ширину ровно 8 бит. обеспечение CHAR_BIT
это 8, uint8_t
может быть определено определением типа для любого 8-битного целого типа без знака, у которого нет битов заполнения.
Вот что говорит черновик стандарта C11 (n1570.pdf):
5.2.4.2.1 Размеры целочисленных типов
1 Значения, приведенные ниже, должны быть заменены константными выражениями, подходящими для использования в #if
директивы предварительной обработки. … их значения, определенные реализацией, должны быть равны или
больше по величине (абсолютное значение), чем показано, с тем же знаком.-- number of bits for smallest object that is not a bit-field (byte) CHAR_BIT 8
Таким образом, самые маленькие объекты должны содержать точно биты CHAR_BIT.
6.5.3.4 Операторы sizeof и _Alignof
…
4 Когда sizeof применяется к операнду с типом char, unsigned
символ или подписанный символ (или его квалифицированная версия), результат
1. …
Таким образом, это (некоторые из) наименьших адресуемых единиц. очевидно int8_t
а также uint8_t
также могут считаться наименьшими адресуемыми единицами, если они существуют.
7.20.1.1 Целочисленные типы с точной шириной
1 Имя typedef intN_t обозначает целочисленный тип со знаком и шириной
N, никаких битов заполнения, и представление дополнения до двух. Таким образом,
int8_t обозначает такой целочисленный тип со знаком шириной ровно 8
биты.2 Имя typedef uintN_t обозначает целочисленный тип без знака с
ширина N и нет отступов. Таким образом, uint24_t обозначает такой неподписанный
целочисленный тип с шириной ровно 24 бита.3 Эти типы являются необязательными. Однако, если реализация обеспечивает
целочисленные типы с шириной 8, 16, 32 или 64 бита, без битов заполнения,
и (для подписанных типов) с дополнением до двух
представление, оно должно определить соответствующие имена typedef.
Акцент наЭти типы являются необязательными«Это мое. Я надеюсь, что это было полезно 🙂
Возможность, о которой еще никто не упомянул: если CHAR_BIT==8
и неквалифицированный char
без знака, который есть в некоторых ABI, то uint8_t
может быть typedef для char
вместо unsigned char
, Это важно, по крайней мере, в той мере, в какой это влияет на выбор перегрузки (и на его злого близнеца, искажение имени), т.е. foo(char)
а также foo(unsigned char)
в области вызова foo
с аргументом типа uint8_t
предпочли бы foo(char)
на такой системе.