我有一个代码库,旨在在没有警告的情况下编译并在多种架构上运行而不会出现任何故障,所有 x86:MSDOS、Windows 32 控制台模式、Windows 32 GUI 模式、Linux 32 和 Linux 64。
在添加对 Linux 64 的支持之前,这很容易。几乎所有数据都被声明int
为 BYTE、WORD 和 DWORD 的 typedef 中的一个或来自 typedef:
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]
由于这段代码的格式非常广泛——数千行输出格式——我宁愿不改造特定类型的格式化程序。使用修饰符回答了z
类似的问题:
printf ("%zu", data);
但这使得 MSDOS 和 Win32 控制台上的 Turbo C 做了一些奇怪的事情:它将转换规范显示%zu
为输出,而不是转换任何东西。
有没有一种更简洁的方法来处理类型的可变性,这种方式与 printf 的粒度和基本数据类型相匹配?