Оператор 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, это унарный +. Операнды унарного + претерпевают "обычные арифметические преобразования". См., Например, этот другой ответ, включающий обычное дополнение.