代码之家  ›  专栏  ›  技术社区  ›  SO Stinks ennuikiller

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

  •  29
  • SO Stinks ennuikiller  · 技术社区  · 15 年前

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

    printf("The about of RAM used is %u", anIntVariable*sizeof(double) );
    

    其中,an int variable是双数组元素数的int变量。无论如何,在32位系统上,我从来没有遇到过任何问题,但是在64位系统上,我收到了一个编译器警告,关于对无符号长整数使用“%u”。使用“%lu”作为格式代码可以解决64位的问题,但会导致编译器对32位的问题提出投诉,因为类型返回到unsigned int。我发现,实际上,sizeof(double)在32位和64位系统上返回的值不同。我找到了一些网页指南 转换 从32位到64位的代码,但我更希望在这两者上都能工作的代码,而不仅仅是来回转换。

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

    3 回复  |  直到 7 年前
        1
  •  20
  •   Lightness Races in Orbit    9 年前

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

    这个include文件有许多可移植的标识符用于特定的运行时。例如,您需要priuptr,这意味着“ 公共关系 因特 牙科医生 u 尺寸达到指针的尺寸”。

    您的示例如下:

    printf("The amount of RAM used is %" PRIuPTR, anIntVariable*sizeof(double) );
    

    使用GCC4.3的64位Linux的结果( int anIntVariable = 1 ):

    $ 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
    

    为了完整性起见,scanf也有标识符,其前缀是scn。

        2
  •  13
  •   wds    11 年前

    size of的返回值是一个大小t。如果您使用的是符合c99的编译器,看起来您可以使用 %zd %zu 为此。

    D'OH: %ZU 当然了。谢谢,我。

        3
  •  7
  •   Thomas Padron-McCarthy    15 年前

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

    其他的回复提供了一些很好的方法,可以用更新的编译器(“%z”和priu32)来处理这个问题,但是我们以前的方法只是将大小转换为unsigned long,然后使用“%lu”打印它:

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

    这在尺寸不超过一个长的系统上不起作用,但我不知道有什么这样的系统,我甚至不确定标准是否允许。