Когда uint8 t ≠ неподписанный символ?
Согласно C и C++, CHAR_BIT >= 8
.
Но всякий раз, когда CHAR_BIT > 8
, uint8_t
даже не может быть представлено в виде 8 бит.
Он должен быть больше, потому что CHAR_BIT
- это минимальное число битов для любого типа данных в системе.
, на какую систему может uint8_t
быть юридически определено, чтобы быть иного типа, чем unsigned char
?
(Если ответ отличается для C и C++ , то я хотел бы знать и то, и другое.)
3 ответа:
Если он существует, то
uint8_t
всегда должен иметь ту же ширину, что иunsigned char
. Однако это не обязательно должен быть один и тот же тип; это может быть отдельный расширенный целочисленный тип. Он также не обязательно должен иметь то же представление, что иunsigned char
; например, биты могут интерпретироваться в обратном порядке. Это глупый пример, но он имеет больше смысла дляint8_t
, гдеsigned char
может быть дополнением единиц или знаком-величиной, в то время какint8_t
требуется, чтобы быть дополнением двоек.Еще одно "преимущество" использования не-char расширенный целочисленный тип для
uint8_t
даже в "нормальных" системах-это правила сглаживания C. Символьные типы могут псевдонимировать все, что угодно, что мешает компилятору сильно оптимизировать функции, которые используют как указатели символов, так и указатели на другие типы, если ключевое слово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) говорит:
Таким образом, самые маленькие объекты должны содержать ровно биты CHAR_BIT.5.2.4.2.1 размеры целых типов 1 приведенные ниже значения заменяются постоянными выражениями, пригодными для использования в #if директивы предварительной обработки. ... Их реализация-определенные значения должны быть равны или больше по величине (абсолютной величине) к показанным, с тем же знак.
-- number of bits for smallest object that is not a bit-field (byte) CHAR_BIT 8
Таким образом, это (некоторые из) наименьших адресуемых единиц. Очевидно, что6.5.3.4 операторы sizeof и _Alignof
...
4 Когда sizeof применяется к операнду, имеющему тип char, unsigned char или подписано чар (или квалифицированного версия оного) результат 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
и unqualifiedchar
является unsigned, что есть в некоторых ABIs, тоuint8_t
может быть typedef дляchar
вместоunsigned char
. Это имеет значение, по крайней мере, в той мере, в какой это влияет на выбор перегрузки (и его злой двойник, искажение имени), Т. е. если бы вы имели обаfoo(char)
иfoo(unsigned char)
в области видимости, вызовfoo
с аргументом типаuint8_t
предпочел быfoo(char)
в такой системе.