C 在32和64平台上使用sizeof的printf:如何以独立于平台的方式处理格式代码?

C 在32和64平台上使用sizeof的printf:如何以独立于平台的方式处理格式代码?,c,32bit-64bit,C,32bit 64bit,我有一些代码可以打印程序使用的内存量。该行与此类似: printf("The about of RAM used is %u", anIntVariable*sizeof(double) ); 其中AnitVariable是双精度数组元素数的整数变量。无论如何,在32位系统上,我从来没有遇到过任何问题,但在64位系统上,我收到一条编译器警告,关于使用“%u”表示无符号长整数。使用“%lu”作为格式代码可以修复64位上的问题,但会导致编译器在32位上抱怨,因为类型返回到unsigned int。

我有一些代码可以打印程序使用的内存量。该行与此类似:

printf("The about of RAM used is %u", anIntVariable*sizeof(double) );
其中AnitVariable是双精度数组元素数的整数变量。无论如何,在32位系统上,我从来没有遇到过任何问题,但在64位系统上,我收到一条编译器警告,关于使用“%u”表示无符号长整数。使用“%lu”作为格式代码可以修复64位上的问题,但会导致编译器在32位上抱怨,因为类型返回到unsigned int。我发现,实际上,sizeof(double)在32位和64位系统上返回的值不同。我找到了一些网页指南,可以将代码从32位转换为64位,但我更希望代码能够同时在这两个位置上工作,而不仅仅是来回转换


如何以独立于平台的方式编写这一行?我知道很多使用预处理器指令的方法,但这看起来像是一个黑客。当然有一种优雅的方式我没有意识到。

可移植的printf标识符在include文件或中提供

这个包含文件有许多可移植的标识符,用于特定的运行时。例如,您需要priupter,这意味着“PRintfIidentifierunsigned的大小不超过指针的大小”

您的示例将是:

printf("The amount of RAM used is %" PRIuPTR, anIntVariable*sizeof(double) );
在使用GCC4.3的64位Linux上的结果(
int-anIntVariable=1
):


为完整起见,scanf也有标识符,其前缀为SCN。

sizeof的返回值是一个size\t。如果您使用的是符合C99标准的编译器,那么您可以使用
%zd
%zu
来实现此目的


D'oh:
%zu
(未签名)当然可以。谢谢,ony。

首先,您应该将“%”说明符与要打印的实际数据类型相匹配sizeof返回数据类型SIZEOT,正如您不应该尝试使用“%d”说明符打印浮点一样,您也不应该尝试打印带有“%u”或“%d”的大小或任何不真正表示大小的内容

其他答复提供了一些很好的方法来处理较新的编译器(“%z”和PRIu32),但我们过去的方法只是将大小转换为unsigned long,然后使用“%lu”打印:


这在尺寸大于长的系统上不起作用,但我不知道有任何这样的系统,我甚至不确定标准是否允许。

问得好。看一看,看:托马斯。你的答案似乎是最好的(在我目前的理解水平下)。造成问题的原因是我假设做(尺寸)将继承AnitVariable的类型,但它不会。我会将该问题保留几天,然后将其标记为已接受的答案。我仍然尚未找到包含(size\t)的表达式的类型提升行为,这与我的问题有关。请注意,win64是一个大小大于长的系统。这个想法似乎回答了我的问题。我已经用C编程很多年了,但我的问题通常是实用的,像可移植性之类的问题很少出现。我有点惊讶于体系结构在如此简单的情况下是如何发挥作用的n、 谢谢,Lira和Thomas,他们有一个不错的变通解决方案,但这似乎是完整的答案。这仍然是不可移植的;它假设
sizeof(size\u t)==sizeof(uintptr\u t)
,这是不能保证的。
PRIuPTR
不工作到“指针大小”;它仅适用于宽度正好为
uintptpr\u t
的整数类型。请注意,在包含之前必须定义\uuu STDC\u格式\u宏,否则将无法使用PRIPTR和类似的宏。(根据ISO C99标准)。如果它已经起作用,则可能是在makefile
中定义的
对于
大小
对于
大小
%zd”
对于
大小
,我猜;)@ony是的,我想这里是
%zu
(编辑了我的答案)。这有点令人困惑,因为代码将有符号的
int
与无符号的
size\t
相乘,其结果应该是无符号整数类型。
$ 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
printf("The amount of RAM used is %lu", (unsigned long)(anIntVariable*sizeof(double)) );