32位环境下size_t被定义为unsigned int, 64位环境下size_t被定义为unsigned long, 对于一个需要同时运行在32位、64位环境的程序来说,在printf或者LOG size_t的时候会比较纠结,一般采用如下第1、2两种方式:
统一转换成unsigned long(或者其他类型):
printf("%lu", (unsigned long)size_t_var);
写起来比较麻烦
#if __WORDSIZE == 64
#define SIZE_T_FMT "%lu"
#else
#define SIZE_T_FMT "%u"
#endif
printf(SIZE_T_FMT, size_t_var);
写起来还是麻烦
实际上,针对size_t类型是有标准的格式串的,不过这里有2个标准格式串:
a) Posix的%zu(小写的z)
b) Gnu的%Zu(大写的Z)
printf(“%zu”, size_t_var); 或者printf(“%Zu”, size_t_var);
写起来非常简单
size_t是unsigned类型,对应的signed类型是ssize_t,ssize_t的格式串是%zd或者%Zd
备注:
man 3 printf的时候,有如下一条说明:
z A following integer conversion corresponds to a size_t or ssize_t argument. (Linux libc5 has Z with thismeaning. Don't use it.)
看起来像是推荐使用大写版本的%Zu/%Zd,不过测试表明大小写版本都能正常工作,保险起见尽量使用大写版本。
32位环境下uint64_t被定义为unsignedlong long, 64位环境下uint64_t被定义为unsigned long, 纠结原因同上面的size_t。传统方式依旧为:1.printf前先强转,2.定义根据环境适配的FMT宏。
不过没有size_t那么幸运,并没有直接针对uint64_t的统一格式串,但是经过一番挖掘后发现,stdint.h有一种类型定义为uintmax_t,跟uint64_t完全等价,而uintmax_t有统一的格式串:%ju。所以在printf/LOG uint64_t时,可以很自然的将%ju用于其中:
printf(“%ju”, uint64_t_var);
uint64_t是unsigned类型,对应的signed类型是int64_t,int64_t的格式串是: %jd