Помимо %hn
и %hhn
(где h
или hh
указывает размер объекта, на который указывает объект), какова точка модификаторов h
и hh
для printf
спецификаторы формата?
Из-за рекламных акций по умолчанию, которые требуются стандарту для применения к вариационным функциям, невозможно передать аргументы типа char
или short
(или любые его подписанные/неподписанные варианты) на printf
.
В соответствии с 7.19.6.1 (7) модификатор h
:
Указывает, что для следующего преобразования d, i, o, u, x или X применяется к short int или unsigned short int (аргумент будет были повышены в соответствии с целыми рекламными акциями, но его стоимость должна преобразовываться в короткий int или unsigned short int перед печатью); или что для указателя на короткий int.
Если аргумент был фактически типа short
или unsigned short
, то продвижение до int
с последующим преобразованием обратно в short
или unsigned short
даст то же значение, что и продвижение до int
, без каких-либо изменение задний. Таким образом, для аргументов типа short
или unsigned short
, %d
, %u
и т.д. Должны давать одинаковые результаты %hd
, %hu
и т.д. (А также для типов char
и hh
).
Насколько я могу судить, единственная ситуация, когда модификатор h
или hh
может быть полезен, - это когда аргумент передал ему int
вне диапазона short
или unsigned short
, например
printf("%hu", 0x10000);
но я понимаю, что передача неправильного типа, как и в результате, приводит к поведению undefined в любом случае, так что вы не могли ожидать, что он будет печатать 0.
Один реальный случай, который я видел, выглядит следующим образом:
char c = 0xf0;
printf("%hhx", c);
когда автор ожидает, что он напечатает f0
, несмотря на то, что реализация имеет простой тип char
, который был подписан (в этом случае printf("%x", c)
будет печатать fffffff0
или аналогичный). Но оправдано ли это ожидание?
(Примечание. Что происходит, так это то, что исходный тип был char
, который получил повышение до int
и преобразован обратно в unsigned char
вместо char
, тем самым изменяя значение, которое печатается. стандарт указывает это поведение, или это деталь реализации, на которую может сломаться сломанное программное обеспечение?)