Правило первое: шансы найти ошибку в библиотеке или компиляторе очень и очень малы. Всегда предполагайте, что компилятор / библиотека верны.
Параметры передаются в printf()
через механизмы в <stdarg.h>
(списки переменных аргументов), что подразумевает некоторую магию в стеке.
Не вдаваясь в подробности, printf()
делает , предполагая , что следующий параметр, который он должен извлечь из стека, имеет тип, указанный в вашей строке формата - в случае %d
, подписано int .
Это работает, если фактическое значение, которое вы ввели, меньше или равно по ширине int
, потому что внутренне любое меньшее значение, передаваемое в стеке, расширяется до ширины int
через механизм под названием " целочисленное продвижение ".
Это не удастся, однако, если тип, который вы передали printf()
, на больше , чем int
: printf()
говорит (вашим %d
) ожидать int
, и извлекает из стека соответствующее количество байтов (предположим, 4 байта для 32-битного int
).
В случае вашего long long
, который мы предполагаем равным 8 байтам для 64-битного значения, это приводит к printf()
получению только половины вашего long long
. Остальное все еще находится в стеке и даст довольно странные результаты, если вы добавите еще %d
в строку формата.
; -)