почему унарные операторы возвращают другой тип, чем их операнды?

Похоже, что унарный побитовый оператор not (~) для uint16_t и uint8_t возвращает int, а не тип своего операнда (то же самое для унарного -). Может ли кто-нибудь объяснить, почему это так?

Неожиданно оказалось, что ~uint16_t(0) ‹ uint16_t(0)

Я использую g++ версии 9.2.1 20191008 (Ubuntu 9.2.1-9ubuntu2) x86_64-linux-gnu


person harelabb    schedule 08.03.2020    source источник
comment
Потому что обычные продвижения всегда выполняются для всех операндов. Оператор ~ работает только с операндами типа int, long, long long, unsigned, unsigned long и unsigned long long. Все остальное требует преобразования.   -  person gnasher729    schedule 08.03.2020


Ответы (1)


Из C++11 Стандарт 5.3.1.8:

Операнд унарного оператора - должен иметь арифметический тип или тип перечисления без области действия, а результатом является отрицание его операнда. Целочисленное повышение выполняется над целочисленными операндами или операндами перечисления. Отрицательное значение беззнаковой величины вычисляется путем вычитания ее значения из 2^n, где n — количество битов в расширенном операнде. Тип результата — это тип расширенного операнда.

Итак, в нем говорится, что целочисленное продвижение происходит для унарных операторов.

person Tarek Dakhran    schedule 08.03.2020
comment
Есть мысли, зачем они это придумали? - person harelabb; 09.03.2020
comment
(Мои личные мысли. Не претендую на правду.) Современное оборудование работает с регистрами, которые обычно имеют фиксированную ширину, например. 64 бит. Чтобы сохранить эффективность языка, имеет смысл продвигать все к регистровой ширине. Представьте, насколько сложным было бы аппаратное обеспечение, если бы вам приходилось обрабатывать только часть регистра. - person Tarek Dakhran; 09.03.2020
comment
Это имеет смысл. И я предполагаю, что регистры предпочитают знаковые значения. - person harelabb; 09.03.2020