printf format specifiers for uint32_t and size_t
我有以下
1 2 3 4 5
| size_t i = 0;
uint32_t k = 0;
printf("i [ %lu ] k [ %u ]
", i , k ); |
编译时收到以下警告:
1
| format ‘%lu’ expects type ‘long unsigned int’, but argument has type ‘uint32_t’ |
当我使用夹板运行时,得到以下信息:
1
| Format argument 1 to printf (%u ) expects unsigned int gets size_t: k |
非常感谢您的任何建议,
-
C89不支持或中的uint32_t; 如果要使用这些类型,则应升级到C89。 作为扩展,很可能GCC允许您使用它们,但是C89没有任何此类支持。
-
和size_t一样,size_t的官方C99格式修饰符是z。
-
stackoverflow.com/questions/1401526/
-
我相信@kennys答案最适合uint32_t,但缺少size_t。 @ u0b34a0f6aes答案包括两者。
-
乔纳森·莱夫勒(Jonathan Leffler)在第一条评论中第二次提及C89应该是C99
尝试
1 2 3 4 5
| #include <inttypes.h>
...
printf("i [ %zu ] k [ %"PRIu32 " ]
", i , k ); |
z表示长度与size_t相同的整数,并且在C99标头inttypes.h中定义的PRIu32宏表示无符号的32位整数。
-
编译时无警告。但夹板不喜欢它。无法识别的格式代码:%zu。第二个。解析错误。 (有关解析错误的帮助,请参阅splint -help parseerrors。)***无法继续。
-
@robUK:嘿。我建议您提交夹板错误。
-
这是正确的答案。虽然我个人的建议是简单地投射,例如printf("%lu", (unsigned long )i )。否则,由于类型更改,最终在整个代码中都会出现一堆警告。
-
这是正确的答案。我同意KennyTM提出的夹板错误。顺便说一句,"%zu"是size_t的正确格式。您不需要任何PRI *宏即可打印size_t。
-
如果我没记错的话,%zu是C99,并且在问题中他写了C89。
-
@alcor是的,他确实放了C89(显然他在使用gcc编译器标志),但是他正在使用uint32_t,因此实际上它是C99代码,应该这样编译。
听起来像您期望size_t与unsigned long(可能是64位)相同,而实际上是unsigned int(32位)。在两种情况下均尝试使用%zu。
我还不
-
编译时无警告。但是,运行夹板时,我得到以下信息:1)printf(%u)期望unsigned int得到uint32_t:i 2)printf(%u)期望unsigned int得到size_t:k
-
听起来好像夹板只是在做书呆子。它可能偏离了源代码中的类型名称,并且没有意识到它们是等效的。我不知道该如何处理@KennyTMs答案……它肯定应该更便携。
-
夹板实际上是在做正确的事。仅仅因为int32_t恰好在您的编译器/平台上是int,并不意味着它在另一个编译器/平台上可能不是long。与size_t相同。实际上,它不费吹灰之力,需要做更多的工作来检测此可移植性错误,因为简单而自然的检查就是像编译器一样尊重typedef。
-
-1,很抱歉其无法携带。所需要做的就是格式说明符和类型同意,并且您始终可以强制使其正确。 long至少为32位,因此%lu和(unsigned long)k始终正确。 size_t比较棘手,这就是为什么在C99中添加了%zu的原因。如果您不能使用它,请像k一样对待它(long是C89中最大的类型,size_t不太可能更大)。
-
请在上面更正。这应该是%zu,而不是%u。
-
更正为%zu
所需要的就是格式说明符和类型一致,并且您始终可以强制使其正确。 long至少为32位,因此%lu和(unsigned long)k始终正确:
1 2 3
| uint32_t k ;
printf("%lu
", (unsigned long)k ); |
size_t比较棘手,这就是为什么在C99中添加了%zu的原因。如果不能使用它,则将其像k一样对待(long是C89中最大的类型,size_t不太可能更大)。
1 2 3 4 5
| size_t sz ;
printf("%zu
", sz ); /* C99 version */
printf("%lu
", (unsigned long)sz ); /* common C89 version */ |
如果没有为所传递的类型指定正确的格式说明符,则printf将等同于从数组中读取过多或过少的内存。只要您使用显式强制转换来匹配类型,它都是可移植的。
如果您不想使用PRI *宏,则打印ANY整数类型的另一种方法是强制转换为intmax_t或uintmax_t并分别使用"%jd"或%ju。这对于未定义PRI *宏的POSIX(或其他OS)类型特别有用,例如off_t。