Оператор Unary + выполняет преобразование типов?
До сих пор я полагал, что нету унарного оператора +
.
Но затем я наткнулся на следующий пример:
char ch;
short sh;
int i;
printf("%d %d %d",sizeof(ch),sizeof(sh),sizeof(i)); // output: 1 2 4
printf("%d %d %d",sizeof(+ch),sizeof(+sh),sizeof(i)); // output: 4 4 4
Означает ли это, что +
выполняет преобразование типов здесь?
Потому что он ведет себя так же, как и
printf("%d %d %d",sizeof((int)ch),sizeof((int)sh),sizeof(i)); // output: 4 4 4
Это заставляет меня думать, что +
выполняет преобразование типов.
Но потом я попробую на double
double f;
printf("%d %d",sizeof(+f),sizeof((int)f),sizeof(f)); // output: 8 4 8
Это заставляет меня переосмыслить об унарном операторе +
.
Итак, мой второй вопрос: имеет ли унарный оператор +
особый эффект в операторе sizeof
?
Ответы
Ответ 1
Unary + выполняет целочисленные аксиомы в своем операнде, мы можем это увидеть, перейдя в проект стандартного раздела C99 6.5.3.3
Унарные арифметические операторы, которые говорят (акцент мой вперед):
Результатом унарного + оператора является значение его (продвинутого) операнд. Целые рекламные акции выполняются в операнде, а результат имеет продвинутый тип.
и раздел 6.3.1
Арифметические операнды говорят:
Если int может представлять все значения исходного типа, это значение равно преобразован в int; в противном случае он преобразуется в unsigned int. Они называются целыми рекламными акциями. 48) Все остальные типы без изменений целыми рекламными акциями.
Обратите внимание, что все остальные типы не изменяются целыми рекламными акциями, и поэтому двойной остается двойным. Это также будет иметь место для float, что не будет повышаться до двух.
Также обратите внимание, что использование %d
для результата sizeof
- это поведение undefined, так как результат равен size_t. надлежащим спецификатором формата будет %zu
.
Ответ 2
Когда меньшие типы участвуют в выражении с более крупными типами (например, char
меньше, чем short
, который в основном меньше int
, который может быть меньше, чем long
), задействованные типы продвигаются к большим тио.
Итак, когда вы используете унарный оператор +
, вы получаете int
, потому что int
- это натуральный целочисленный тип в C.
Что касается типа double
, естественный тип с плавающей точкой для C равен double
, поэтому нет продвижения по значениям или переменным, которые уже имеют тип double
.
Оператор sizeof
не имеет к этому никакого отношения.
Ответ 3
Оператор унарный +
запускает "начальные" обычные арифметические преобразования, поэтому все целочисленные операнды, тип которых имеет более низкий ранг, чем ранг int
и unsigned int
, повышаются до int
(или unsigned int
, если int
не распространяется на все значения типа, продвигаемого по этой реализации).
Ответ 4
Это не sizeof
, это унарный +
. Операнды унарного +
претерпевают "обычные арифметические преобразования". См., Например, этот другой ответ, включающий обычное дополнение.