在跨平台的c/c ++项目(Win32,Linux,OSX)中,我需要使用*printf函数来打印一些size_t类型的变量.在某些环境中,size_t是8个字节,而在其他环境中它们是4.在glibc上我有%zd,在Win32上我可以使用%Id.有一种优雅的方式来处理这个问题吗?
的PRIuPTR
宏(从uintptr_t
,这应该总是足够大,则可以施放size_t
到它不截断,例如
fprintf(stream, "Your size_t var has value %" PRIuPTR ".", (uintptr_t) your_var);
这里真的有两个问题.第一个问题是三个平台的正确printf说明符字符串是什么.请注意,这size_t
是一种无符号类型.
在Windows上,使用" %Iu
".
在Linux和OSX上,使用" %zu
".
第二个问题是如何支持多个平台,因为格式字符串之类的东西可能在每个平台上都不同.正如其他人所指出的那样,使用#ifdef
会很快变得难看.
而是为每个目标平台编写单独的makefile或项目文件.然后通过源文件中的某个宏名称引用说明符,在每个makefile中相应地定义宏.特别是,GCC和Visual Studio都接受"D"开关来在命令行上定义宏.
如果您的构建系统非常复杂(多个构建选项,生成的源等),维护3个单独的makefile可能会变得难以处理,并且您将不得不使用某种高级构建系统,如CMake或GNU autotools.但基本原理是相同的 - 使用构建系统来定义特定于平台的宏,而不是将平台检测逻辑放在源文件中.
我唯一能想到的是典型的:
#ifdef __WIN32__ // or whatever #define SSIZET_FMT "%ld" #else #define SSIZET_FMT "%zd" #endif
然后利用恒定折叠:
fprintf(stream, "Your size_t var has value " SSIZET_FMT ".", your_var);