Когда у нас есть выражение E1 ? E2 : E3
, здесь задействованы четыре типа. Выражения E1
, E2
и E3
имеют тип (и типы E2
и E3
могут быть разными). Кроме того, все выражение E1 ? E2 : E3
имеет тип.
Если E2
и E3
имеют один и тот же тип, это легко: общее выражение имеет этот тип. Мы можем выразить это в мета-записи, как это:
(T1 ? T2 : T2) -> T2
"The type of a ternary expression whose alterantives are both of the same type T2
is just T2."
Если они не имеют такого же типа, вещи получить немного интересно, и ситуация очень похожа на E2
и E3
будучи вовлеченным вместе в арифметике операция. Например, если вы добавляете вместе int
и float
, операнд int
преобразуется в float
. Это то, что происходит в вашей программе. Ситуация тип:
(int ? float : int) -> float
тест не пройден, и поэтому значение 0
int
преобразуется в значение 0.0
float
.
Это float
значение не является совместимым с %d
спецификатором преобразования из printf
, который требует int
.
Точнее, значение float
претерпевает еще одно.Когда float
передается как один из возвращающих аргументов вариационной функции, он преобразуется в double
.
Таким образом, на самом деле значение double
0.0 передается в printf
, где ожидается int
.
В любом случае это неопределенное поведение: это непереносимый код, для которого стандартное определение языка C не имеет смысла.
С этого момента мы можем применить аргументы, основанные на платформе, почему мы не просто видим 0
. Предположим, что int
- это 32-разрядный, четырехбайтовый тип, а double
- это общее представление 64-битного, 8-байтового, IEE754 и что для 0.0
используется бит с битами. Итак, почему же не 32-разрядная часть этого бита-нуля равна printf
как int
значение 0
?
Вполне возможно, что значение аргумента 64 бит double
заставляет 8-байтовое выравнивание, когда оно помещено в стек, возможно, перемещая указатель стека на четыре байта. И тогда printf
вытаскивает мусор из этих четырех байтов, а не нулевые биты из значения double
.
Что именно вы подразумеваете под «случайным»? Вы пытаетесь напечатать число с плавающей точкой как целое число, но это число должно быть '0', которое имеет одинаковое представление бит в обоих типах. –
Случайный, или просто некорректный? –
Этот вопрос кажется не по теме, потому что речь идет о том, кто знает что. –