printof with sizeof on 32 vs 64 platform:如何以独立于平台的方式处理格式代码?

Dr.*_* II 29 c 32bit-64bit

我有一些代码打印程序使用的内存量.该行类似于:

printf("The about of RAM used is %u", anIntVariable*sizeof(double) );
Run Code Online (Sandbox Code Playgroud)

其中anIntVariable是double数组元素数的int变量.无论如何,在32位系统上我从来没有遇到任何问题,但在64位系统上,我得到一个编译器警告关于使用"%u"作为无符号长整数.使用"%lu"作为格式代码可以解决64位问题,但会导致编译器抱怨32位,因为类型返回unsigned int.我发现,确实,sizeof(double)在32位与64位系统上返回不同的值.我找到了一些网页指南,用于代码从32位转换为64位但是我宁愿让代码同时适用于两者而不仅仅是来回转换.

如何以独立于平台的方式编写此行?我知道很多方法可以使用预处理器指令来实现它,但这似乎是一个黑客攻击.当然有一种我没有意识到的优雅方式.

Lir*_*una 20

include文件中提供了可移植的printf标识符inttypes.h.

此包含文件具有适用于特定运行时的许多可移植标识符 对于你的榜样,你要PRIuPTR,这意味着" PR INTF dentifier ü nsigned最高为指针的尺寸大小".

那么你的例子将是:

printf("The amount of RAM used is %" PRIuPTR, anIntVariable*sizeof(double) );
Run Code Online (Sandbox Code Playgroud)

使用GCC 4.3(int anIntVariable = 1)的64位Linux上的结果:

$ gcc test.c -m32 -o test && ./test
The amount of RAM used is 8
$ gcc test.c -o test && ./test
The amount of RAM used is 8
Run Code Online (Sandbox Code Playgroud)

为了完整起见,还有scanf的标识符,其前缀为SCN.

  • 这仍然不便于携带;它假设“sizeof(size_t) == sizeof(uintptr_t)”,但这是无法保证的。`PRIuPTR` 不能“达到指针大小”;它仅适用于**完全**“uintptr_t”宽度的整数类型。 (2认同)

wds*_*wds 13

sizeof的返回值是size_t.如果您使用的是C99兼容的编译器,看起来您可以使用它.%zd%zu

D'哦:%zu当然是(未签名).谢谢,嘿.


Tho*_*thy 7

首先,您应该将"%"说明符与要打印的实际数据类型相匹配.sizeof返回数据类型size_t,正如您不应该尝试使用"%d"说明符打印浮点数一样,您不应该尝试使用"%u"或"%d"打印size_t或者不打印任何内容这真的是指size_t.

其他回复给出了一些很好的方法来处理这个新的编译器("%z"和PRIu32),但我们以前的方式只是将size_t转换为unsigned long,然后使用"%lu"打印它:

printf("The amount of RAM used is %lu", (unsigned long)(anIntVariable*sizeof(double)) );
Run Code Online (Sandbox Code Playgroud)

这对于s​​ize_t比long更宽的系统不起作用,但我不知道任何这样的系统,我甚至不确定标准是否允许它.

  • 请注意,win64是size_t宽于long的系统. (3认同)