Когда uint8_t char беззнаковый символ?

Согласно C и C ++, CHAR_BIT >= 8,
Но всякий раз, когда CHAR_BIT > 8, uint8_t даже не может быть представлен как 8 бит.
Это должно быть больше, потому что CHAR_BIT минимальное количество бит для любого типа данных в системе.

На какую систему можно uint8_t быть юридически определенным как тип, отличный от unsigned char?

(Если ответ для C и C ++ разный, то я хотел бы знать оба.)

56

Решение

Если он существует, uint8_t должна всегда иметь ту же ширину, что и unsigned char, Однако это не обязательно должен быть тот же тип; это может быть отдельный расширенный целочисленный тип. Это также не должно иметь такое же представление, как unsigned char; например, биты могут быть интерпретированы в обратном порядке. Это глупый пример, но он имеет больше смысла для int8_t, где signed char может быть дополнением или знаком int8_t должен быть дополнением до двух.

Еще одно «преимущество» использования расширенного целочисленного типа, не являющегося символом, для uint8_t даже на «нормальных» системах есть правила псевдонимов Си. Символьным типам разрешено псевдонимом чего угодно, что не позволяет компилятору сильно оптимизировать функции, которые используют как символьные указатели, так и указатели на другие типы, если только restrict Ключевое слово было применено хорошо. Однако, даже если uint8_t имеет точно такой же размер и представление, как unsigned charесли реализация сделала его отличным, не символьным типом, правила псевдонимов не будут применяться к нему, и компилятор может предположить, что объекты типов uint8_t а также intНапример, никогда не может псевдоним.

53

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

На какую систему можно 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.

Акцент наЭти типы являются необязательными«Это мое. Я надеюсь, что это было полезно 🙂

30

Возможность, о которой еще никто не упомянул: если CHAR_BIT==8 и неквалифицированный char без знака, который есть в некоторых ABI, то uint8_t может быть typedef для char вместо unsigned char, Это важно, по крайней мере, в той мере, в какой это влияет на выбор перегрузки (и на его злого близнеца, искажение имени), т.е. foo(char) а также foo(unsigned char) в области вызова foo с аргументом типа uint8_t предпочли бы foo(char) на такой системе.

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