用宏检测 gcc 而不是 msvc/clang

我正在从事一个项目,已建立与 gcc 和 msvc 到目前为止。我们最近也开始用当声构建。

代码中有一些特定于平台的部分:

#ifndef _WIN32
// ignore this in msvc
#endif

由于 gcc 以前是唯一的非 windows 版本,这相当于说“只为 gcc 做这件事”。但是现在它的意思是“仅对 gcc 和 clang 执行此操作”。

但是仍然存在一些情况,我希望处理一些特定于 gcc 的内容,而不是处理 clang。检测 gcc 是否有一种简单而有效的方法,即。

#ifdef ???
// do this *only* for gcc
#endif
47792 次浏览
__GNUC__
__GNUC_MINOR__
__GNUC_PATCHLEVEL__

These macros are defined by all GNU compilers that use the C preprocessor: C, C++, Objective-C and Fortran. Their values are the major version, minor version, and patch level of the compiler, as integer constants. For example, GCC 3.2.1 will define __GNUC__ to 3, __GNUC_MINOR__ to 2, and __GNUC_PATCHLEVEL__ to 1. These macros are also defined if you invoke the preprocessor directly.

Also:

__GNUG__

The GNU C++ compiler defines this. Testing it is equivalent to testing (__GNUC__ && __cplusplus).

Source

Apparently, clang uses them too. However it also defines:

__clang__
__clang_major__
__clang_minor__
__clang_patchlevel__

So you can do:

#ifdef __GNUC__
#ifndef __clang__
...

Or even better (note the order):

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

With Boost, this becomes very simple:

#include <boost/predef.h>


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

See also the Using the predefs section of the boost documentation.

(credit to rubenvb who mentioned this in a comment, to Alberto M for adding the include, and to Frederik Aalund for correcting #ifdef to #if)

I use this define:

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

And test with it:

#if GCC_COMPILER
...
#endif