我遇到了gcc v3.4.4的bug,并希望在我的代码中加入#ifdef来解决这个版本编译器的bug。
如何使用GCC编译器预处理器预定义宏来检测编译器的版本号?
我遇到了gcc v3.4.4的bug,并希望在我的代码中加入#ifdef来解决这个版本编译器的bug。
如何使用GCC编译器预处理器预定义宏来检测编译器的版本号?
来自gnu cpp手册...
__GNUC__
__GNUC_MINOR__
__GNUC_PATCHLEVEL__
这些宏由使用 C 预处理器的所有 GNU 编译器定义:C、C++、Objective-C 和 Fortran。它们的值是编译器的主要版本、次要版本和补丁级别,作为整数常量。例如,GCC 3.2.1 将定义 __GNUC__
为 3,__GNUC_MINOR__
为 2,__GNUC_PATCHLEVEL__
为 1。如果直接调用预处理器,这些宏也会被定义。
__GNUC_PATCHLEVEL__
是 GCC 3.0 中新引入的;在 3.0 前广泛使用的开发快照中也存在(这些快照自称为 GCC 2.96 或 2.97,具体取决于您拥有的快照版本)。
如果您只需要知道您的程序是否由 GCC 编译,或者由声称接受 GNU C 方言的非 GCC 编译器编译,则可以简单地测试 __GNUC__
。如果您需要编写依赖于特定版本的代码,则必须更加小心。每次增加次要版本时,补丁级别将重置为零;每次增加主要版本(这很少发生)时,次要版本和补丁级别都会重置。如果您希望直接在条件语句中使用预定义的宏,则需要编写如下代码:
/* Test for GCC > 3.2.0 */
#if __GNUC__ > 3 || \
(__GNUC__ == 3 && (__GNUC_MINOR__ > 2 || \
(__GNUC_MINOR__ == 2 && \
__GNUC_PATCHLEVEL__ > 0)))
__GNUC__
、__GNUC_MINOR__
和 __GNUC_PATCHLEVEL__
。
例如,GCC 4.0.1 将会:
#define __GNUC__ 4
#define __GNUC_MINOR__ 0
#define __GNUC_PATCHLEVEL__ 1
当你想知道在当前编程环境下GNU GCC编译器所定义的预定义预处理指令时,可以记住以下这个简单的命令行:
gcc -E -dM - < /dev/null |less
gcc -E -dM - < /dev/null | sort | less
- Bart有3个gcc版本的宏可供测试。
__GNUC_MINOR__
__GNUC_PATCHLEVEL__
__GNUC__
#define __GNUC_MINOR__ 1
#define __GNUC_PATCHLEVEL__ 3
#define __GNUC__ 4
该命令与C语言编译器相关,可用于显示当前环境中定义的所有预定义宏。gcc -E -dM -x c /dev/null
顺便提一下,如果您正在使用glib,则可以访问以下宏,该宏可用于检查GNU C/C++编译器版本:
#ifdef __GNUC__
#define G_GNUC_CHECK_VERSION(major, minor) \
((__GNUC__ > (major)) || \
((__GNUC__ == (major)) && \
(__GNUC_MINOR__ >= (minor))))
#else
#define G_GNUC_CHECK_VERSION(major, minor) 0
#endif
#define SNAPDEV_CHECK_VERSION(wanted_major, wanted_minor, wanted_patch, current_major, current_minor, current_patch) \
(((current_major) > (wanted_major)) || \
(((current_major) == (wanted_major)) \
&& (((current_minor) > (wanted_minor)) || \
(((current_minor) == (wanted_minor)) \
&& ((current_patch) >= (wanted_patch))))))
我有一个专门为GCC设计的检查,因此您不必记住包括版本在内的宏名称:
#define SNAPDEV_CHECK_GCC_VERSION(wanted_major, wanted_minor, wanted_patch) \
SNAPDEV_CHECK_VERSION(wanted_major, wanted_minor, wanted_patch, \
__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
就像我对我的大部分代码一样,我编写了一个单元测试,这样我就可以说,除非您提供无效数据(臭名昭著的最后一句话),否则测试不太可能失败。