Detect gcc as opposed to msvc / clang with macro
Solution 1
__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).
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)
....
Solution 2
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
)
Solution 3
I use this define:
#define GCC_COMPILER (defined(__GNUC__) && !defined(__clang__))
And test with it:
#if GCC_COMPILER
...
#endif

ValarDohaeris
Updated on July 05, 2022Comments
-
ValarDohaeris 11 months
I am working on a project that has been built with both gcc and msvc so far. We recently started building with clang as well.
There are some parts in the code, where platform-specific things are done:
#ifndef _WIN32 // ignore this in msvc #endif
Since gcc has previously been the only non-windows build, this was equivalent to saying "do this only for gcc". But now it means "do this only for gcc and clang".
However there are still situations, where I would like to handle something specifically for gcc, and not for clang. Is there a simple and robust way to detect gcc, i.e.
#ifdef ??? // do this *only* for gcc #endif
-
rubenvb over 8 yearsThese things are all collected in the much more robust Boost.Predef, and the (now outdated) original wiki that sprung that Boost library is located here. Note that the Intel compiler will define
__GNUC__
or_MSC_VER
on the relevant platforms as well. -
Peter Cordes over 6 yearsAll compilers that support the GNU C set of language extensions define those macros, right down to
__GNUC_PATCHLEVEL__
. So to detect support for a specific GNU C feature on any compiler, you check those macros. On gcc itself, they also map to the actual version of the compiler you're using, but they're best used to tell you what version of the GNU C language is supported, more than the compiler type / version. -
Alberto M about 6 yearsThe header to include to get the symbol is
<boost/predef.h>
. -
Frederik Aalund over 5 yearsYou're supposed to use
#if BOOST_COMP_GNUC
and not#ifdef
since the macro is always defined (but may be zero). See boost.org/doc/libs/1_66_0/doc/html/predef/… -
ValarDohaeris over 5 yearsYes, thanks for pointing it out, I thought I tested this when I first posted the answer, but it looks like
#ifdef
probably never worked, at least not for boost versions 1.55 or later. -
Peter Cordes over 4 yearsThat won't exclude ICC.
-
Ayxan Haqverdili about 4 years@PeterCordes why not
-
Peter Cordes about 4 years@Ayxan: because ICC supports GNU extensions, and thus defines
__GNUC__
. You'd also have to check for!defined(__INTEL_COMPILER)
, like for clang. software.intel.com/en-us/forums/intel-c-compiler/topic/281802 -
SimonC almost 4 yearsNote that using Boost isn't always the correct solution. Boost can be handy, indeed, but thanks to its size and complexity, can add a large amount of overhead.#
-
Knitschi about 2 yearsThis does not seem to work when using clang-cl. In this case
__clang__
and_MSC_VER
is defined.