【发布时间】:2011-06-02 23:38:34
【问题描述】:
除了%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 转换说明符适用于指向 short 的指针 int 参数。
如果参数实际上是 short 或 unsigned short 类型,则提升到 int 然后转换回 short 或 unsigned short 将产生与升级到int 没有任何转换回来。因此,对于short 或unsigned short 类型的参数,%d、%u 等应该给出与%hd、%hu 等相同的结果(同样对于char 类型和@987654345 @)。
据我所知,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,从而改变了打印的值。但是标准指定了这种行为,还是损坏的软件可能依赖的实现细节?)
【问题讨论】:
标签: c printf variadic-functions promotions format-specifiers