在添加对 Linux 64 的支持之前,这很容易。几乎所有数据都被声明为 int
或来自 BYTE、WORD 和 DWORD 的类型定义:
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
添加 64 位 gcc 支持后,DWORD 需要稍微调整以保持 32 位值,因为它代表存储的数据:
// to compile DWORDs as 32 bits on 64-bit machines:
#if __x86_64__
typedef unsigned int DWORD;
#else
typedef unsigned long DWORD;
#endif
这在所有环境中都运行良好:
DWORD data;
printf ("%lu", data);
但是,gcc -Wall
现在会提示格式转换:
warning: format ‘%ld’ expects argument of type ‘long int’, but argument
1 has type ‘DWORD {aka unsigned int}’ [-Wformat]
由于这段代码的大量格式化——数千行输出格式化——我宁愿不改造特定类型的格式化程序。类似的问题是 answered by using the z
modifier :
printf ("%zu", data);
但这使得 MSDOS 和 Win32 控制台上的 Turbo C 做了一些奇怪的事情:它显示转换规范 %zu
作为输出而不是转换任何东西。
是否有更简洁的方法来处理类型的可变性,使其符合 printf 的粒度和基本数据类型?
最佳答案
我认为你最不坏的可用选择是从概念上借用 <inttypes.h>
:
#ifdef _LP64
#define PRIdword "d"
#define PRIudword "u"
#else
#define PRIdword "ld"
#define PRIudword "lu"
#endif
然后
DWORD data;
printf("%"PRIdword, data);
这利用了所有 C90 兼容的编译器都应该支持的字符串常量连接。请注意,要测试的正确宏是 _LP64
, 不是 __x86_64__
;这样,当您转到其他 LP64 系统或 Linux/x86-64(32 位指针,宽寄存器)的 Shiny 新“x32”模式时,它就会正常工作。
投资大规模转换为 <stdint.h>
可能不是一个坏主意类型,但这不会让你摆脱这种事情,你只是在写
int32_t data;
printf("%"PRId32, data);
相反,据我所知大多数 Windows 编译器仍然没有<inttypes.h>
,感叹。
如果您想知道,%
不在宏内,因此您可以根据需要放入格式调整器:
printf("%-32"PRIdword, data);
关于c++ - %ld 格式转换以实现便携性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16949445/