I have a code base which is intended to compile without warnings and run without any glitches on multiple architectures, all x86: MSDOS, Windows 32 console mode, Windows 32 GUI mode, Linux 32, and Linux 64.
Before adding support of Linux 64, this was easy. Almost all data were declared as either int
or from the typedefs for BYTE, WORD, and DWORD:
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
Upon adding 64-bit gcc support, DWORD needed a little tweaking to remain as a 32 bit value since it represented stored data:
// to compile DWORDs as 32 bits on 64-bit machines:
#if __x86_64__
typedef unsigned int DWORD;
#else
typedef unsigned long DWORD;
#endif
And this worked nicely on all environments:
DWORD data;
printf ("%lu", data);
However, gcc -Wall
now complains about format conversions:
warning: format ‘%ld’ expects argument of type ‘long int’, but argument
1 has type ‘DWORD {aka unsigned int}’ [-Wformat]
Due to the extensive formatting this code does—thousands of lines of output formatting—I'd rather not retrofit a type specific formatter. A similar question was answered by using the z
modifier:
printf ("%zu", data);
But that makes Turbo C on MSDOS and Win32 console do something odd: It shows the conversion specification %zu
as output instead of converting anything.
Is there a cleaner way to handle the variability of the type in a way that goes with the grain of printf and the fundamental data types?