Нет ничего волшебного c в передаче этих значений printf
. Помните, его прототип - int printf(const char*, ...)
. Когда числовой аргумент c, который меньше int
, передается через многоточие (...
в конце списка аргументов), он переводится в int
. Таким образом, printf
ожидает, что все значения, типы которых меньше, чем int
, будут переданы как int
.
Однако в этом случае интегральные продвижения отсутствуют. Тип -32768
является int
. То же самое для -32769
. Это зависит от кода внутри printf
, чтобы применить спецификатор формата (здесь "%hd"
) и попытаться найти смысл в значениях, которые ему передаются. Этот код передает целочисленные значения и утверждает, что их тип short
. Похоже, что это работает, но, в общем, не ожидайте от этого смысла.
Относительно (short)-32768
, если это значение соответствует короткому (что, вероятно, и делает; проверьте SHORT_MIN
, чтобы выяснить, ), нет проблем. Если нет, результат преобразования определяется реализацией; это не незаконно.
И, наконец, -32769
имеет тип int
; переполнения нет, и результат, который вы видите, - это просто код форматирования, пытающийся разобраться в битовом шаблоне, исходя из предположения, что значение, которое он видит, является результатом повышения от short
до int
. Опять же, не ожидайте от этого смысла.