Страницы

Поиск по вопросам

среда, 26 февраля 2020 г.

Продвигаются ли целые типы при битовых сдвигах?

#cpp #c #продвижение #integer #promotions


Мне известно, что малые типы продвигаются до int или unsigned int (зависит от реализации).

Меня интересует следующий вопрос.

Довольно часто вижу такой код:

uint8_t a, b, c, d;
// ...
uint32_t dword = (a << 24) | (b << 16) | (c << 8) | d;


Или такой:

uint8_t a, b;
// ...
uint16_t word = (a << 8) | b;


Верен ли этот код? Я сам считаю, что верен, потому что a, b, c и d должны продвигаться
до int или unsigned int, поэтому величины не сдвигаются более, чем на ширину типа,
и неопределенного поведения не возникает.
    


Ответы

Ответ 1



Согласно стандарту C++ 7.3.6 Integral promotions [conv.prom] 1 A prvalue of an integer type other than bool, char16_t, char32_t, or wchar_t whose integer conversion rank (6.7.4) is less than the rank of int can be converted to a prvalue of type int if int can represent all the values of the source type; otherwise, the source prvalue can be converted to a prvalue of type unsigned int. и 7.6.7 Shift operators [expr.shift] 1 The shift operators << and >> group left-to- right. The operands shall be of integral or unscoped enumeration type and integral promotions are performed. The type of the result is that of the promoted left operand. The behavior is undefined if the right operand is negative, or greater than or equal to the range exponent of the promoted left operand и 7.6.12 Bitwise exclusive OR operator 1 The operands shall be of integral or unscoped enumeration type. The usual arithmetic conversions (7.4) are performed. Given the coefficients xi and > yi of the base-2 representation (6.7.1) of the converted operands x and y, the coefficient ri of the base-2 representation of the result r is 1 if either (but not both) of xi and yi are 1, and 0 otherwise. [Note: The result is the bitwise exclusive OR function of the operands. — end note] Имейте в виду, что usual arithmetic conversions включают в себя integral promotions. Таким образом в данном фрагменте кода uint8_t a, b, c, d; // ... uint32_t dword = (a << 24) | (b << 16) | (c << 8) | d; операнды a, b, c, d преобразуются к типу int перед выполнением операций.

Комментариев нет:

Отправить комментарий