当前位置:  开发笔记 > 编程语言 > 正文

用于size_t类型变量的跨平台格式字符串?

如何解决《用于size_t类型变量的跨平台格式字符串?》经验,为你挑选了3个好方法。

在跨平台的c/c ++项目(Win32,Linux,OSX)中,我需要使用*printf函数来打印一些size_t类型的变量.在某些环境中,size_t是8个字节,而在其他环境中它们是4.在glibc上我有%zd,在Win32上我可以使用%Id.有一种优雅的方式来处理这个问题吗?



1> finnw..:

PRIuPTR宏(从还)定义为一个十进制格式uintptr_t,这应该总是足够大,则可以施放size_t到它不截断,例如

fprintf(stream, "Your size_t var has value %" PRIuPTR ".", (uintptr_t) your_var);


如果它是C++,那么在包含之前不要忘记定义__STDC_FORMAT_MACROS.

2> 小智..:

这里真的有两个问题.第一个问题是三个平台的正确printf说明符字符串是什么.请注意,这size_t是一种无符号类型.

在Windows上,使用" %Iu".

在Linux和OSX上,使用" %zu".

第二个问题是如何支持多个平台,因为格式字符串之类的东西可能在每个平台上都不同.正如其他人所指出的那样,使用#ifdef会很快变得难看.

而是为每个目标平台编写单独的makefile或项目文件.然后通过源文件中的某个宏名称引用说明符,在每个makefile中相应地定义宏.特别是,GCC和Visual Studio都接受"D"开关来在命令行上定义宏.

如果您的构建系统非常复杂(多个构建选项,生成的源等),维护3个单独的makefile可能会变得难以处理,并且您将不得不使用某种高级构建系统,如CMake或GNU autotools.但基本原理是相同的 - 使用构建系统来定义特定于平台的宏,而不是将平台检测逻辑放在源文件中.


适合指出`%Iu`(win)和`%zu`(mac/linux),它们比问题建议更正式.Windows正式定义了`_WIN32`宏,我个人发现开发更容易依赖于基于这个宏而不是每个平台makefile的小的,集中的`#ifdef`.虽然我使用Visual Studio和Xcode,它们也有效地拥有自己的makefile版本.不同之处在于最小化宏定义的数量和`#ifdef`情况.

3> tzot..:

我唯一能想到的是典型的:

#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);

推荐阅读
yzh148448
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有