я работаю с libvma и мы выдвинули этот коммит для компиляции с gcc7. я не уверен, какой уровень переполнения мы использовали (я думаю, по умолчанию)
о%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 (аргумент будет повышен в соответствии с целочисленными предложениями, но его значение должно быть преобразовано в short int или unsigned short int перед печатью); или что следующий n-й спецификатор преобразования применяется к указателю на короткий аргумент 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);
но я понимаю, что передача неправильного типа, подобного этому, в любом случае приводит к неопределенному поведению, так что вы не можете ожидать, что он выведет 0.
Один случай из реальной жизни, который я видел, это такой код:
char c = 0xf0;
printf("%hhx", c);
где автор ожидает его напечататьf0
несмотря на реализацию, имеющую простойchar
тип, который подписан (в этом случае,printf("%x", c)
будет печататьfffffff0
или похожие). Но оправдано ли это ожидание?
(Примечание: происходит то, что оригинальный типchar
, который получает повышение вint
и преобразован обратно вunsigned char
вместоchar
, таким образом, изменяя значение, которое будет напечатано. Но стандарт определяет это поведение, или это - деталь реализации, на которую может полагаться сломанное программное обеспечение?)