使用宏检测gcc而不是msvc / clang

时间:2015-01-27 09:00:27

标签: c++ gcc

到目前为止,我正在开发一个用gcc和msvc构建的项目。我们最近也开始用clang构建。

代码中有一些部分,特定于平台的事情已经完成:

#ifndef _WIN32
// ignore this in msvc
#endif

由于gcc以前是唯一的非windows版本,这相当于说"仅对gcc"这样做。但现在它意味着"只为gcc和clang"。

做这件事

然而,仍有一些情况,我想专门针对gcc处理某些事情,而不是针对clang。是否有一种简单而强大的方法来检测gcc,即

#ifdef ???
// do this *only* for gcc
#endif

4 个答案:

答案 0 :(得分:55)

__GNUC__
__GNUC_MINOR__
__GNUC_PATCHLEVEL__
  

这些宏由所有使用C预处理器的GNU编译器定义:C,C ++,Objective-C和Fortran。它们的值是编译器的主要版本,次要版本和补丁级别,作为整数常量。例如,GCC 3.2.1将__GNUC__定义为3,将__GNUC_MINOR__定义为2,将__GNUC_PATCHLEVEL__定义为1.如果直接调用预处理器,也会定义这些宏。

此外:

__GNUG__
  

GNU C ++编译器对此进行了定义。测试它等同于测试(__GNUC__&& __cplusplus)。

Source

显然,clang也使用它们。但它也定义了:

__clang__
__clang_major__
__clang_minor__
__clang_patchlevel__

所以你可以这样做:

#ifdef __GNUC__
    #ifndef __clang__
...

甚至更好(注意顺序):

#if defined(__clang__)
....
#elif defined(__GNUC__) || defined(__GNUG__)
....
#elif defined(_MSC_VER)
....

答案 1 :(得分:9)

使用Boost,这变得非常简单:

#include <boost/predef.h>

#if BOOST_COMP_GNUC
// do this *only* for gcc
#endif

另请参阅增强文档的Using the predefs部分。

(感谢rubenvb在评论中提及此问题,感谢Alberto M添加了包含,并向Frederik Aalund提出纠正#ifdef#if

答案 2 :(得分:2)

我用这个定义:

#define GCC_COMPILER (defined(__GNUC__) && !defined(__clang__))

用它测试:

#if GCC_COMPILER
...
#endif

答案 3 :(得分:1)

__GNUG__可能是您最好的选择 - 请参阅here。它专门针对GNU C ++进行测试,而不仅仅是__GNUC__的GNU C / C ++ / FORTRAN编译器 - 即“等同于测试(__GNUC__ && __cplusplus)