Ответ 1
Тип a? b: c
a? b: c
не зависит от a
. Это определено безоговорочно типами b
и c
. Полные правила сложны, но для арифметических операндов тип определяется обычными арифметическими преобразованиями. По сути, два операнда преобразуются в общий тип. Для int
и unsigned int
результирующий тип будет unsigned int
.
Условный оператор ? :
? :
описано в п. 6.5.15 стандарта C 2018. В параграфе 4 говорится, что результат "преобразован в тип, описанный ниже".
Параграф 5 описывает результат для арифметических типов, структур и объединений:
Если и второй, и третий операнды имеют арифметический тип, тип результата, который будет определен обычными арифметическими преобразованиями, если бы они применялись к этим двум операндам, является типом результата. Если оба операнда имеют структуру или тип объединения, результат имеет этот тип. Если оба операнда имеют тип void, результат имеет тип void.
Арифметические типы - это целочисленные типы и типы с плавающей точкой, согласно 6.2.5 18. (К ним относятся как действительные, так и сложные типы.) Обычные арифметические преобразования описаны в 6.3.1.8 1, которые (в моем резюме, не указаны):
- Если какой-либо из них является сложным типом, результат является сложным, а остальные правила описывают тип действительной и мнимой частей. В противном случае результат является реальным, а остальные правила описывают его тип.
- Если любой из них
long double
, результат будетlong double
. - В противном случае, если один из них
double
, результатdouble
. - В противном случае, если любой из них является
float
, результатом будетfloat
. - В противном случае целочисленные преобразования применяются к каждому операнду (они указаны в 6.3.1.1 2), а затем оба типа преобразуются в общий целочисленный тип. Полные правила для этого несколько сложны, используют концепцию ранга, которая требует некоторого объяснения, и охватывают некоторые эзотерические ситуации, поэтому я просто суммирую их для нормальных ситуаций: если оба типа являются
int
или более узкими (имеется в виду меньше битов или одинаковое число) битов, но подписан вместо без знака), результат -int
. В противном случае, если оба являютсяunsigned int
или уже, результатом будетunsigned int
. В противном случае результат будет более широкого типа.
Правила структуры, объединения и пустоты понятны: два операнда должны иметь одинаковый тип, и это результат.
Параграф 6 описывает результат для указателей:
Если и второй, и третий операнды являются указателями или один является константой нулевого указателя, а другой является указателем, тип результата является указателем на тип, квалифицированный всеми квалификаторами типов типов, на которые ссылаются оба операнда. Кроме того, если оба операнда являются указателями на совместимые типы или на версии с разными квалификациями совместимых типов, тип результата представляет собой указатель на версию с соответствующим квалификацией составного типа; если один операнд является константой нулевого указателя, результат имеет тип другого операнда; в противном случае один операнд является указателем на void или квалифицированной версией void, и в этом случае тип результата является указателем на соответствующую квалифицированную версию void.
В итоге, это говорит:
- Если у любого из операндов есть квалификаторы (
const
,volatile
,restrict
или_Atomic
),_Atomic
их в тип результата. - Если два типа различны, но совместимы (например, массив неизвестного размера и массив известного размера, оба с одинаковым типом элементов), объедините эти два типа. (Другие возможности объединения, помимо размера массива, включают элементы массивов, отличающихся друг от друга, но совместимых типов, функцию с и без списка параметров, а параметры функций - разные, но совместимые типы.)