Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect gcc as opposed to msvc / clang with macro

Tags:

c++

gcc

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 
like image 496
ValarDohaeris Avatar asked Jan 27 '15 09:01

ValarDohaeris


People also ask

Is GCC better than MSVC?

GCC is a fine compiler, and can produce code that has pretty much the same performance, if not better, than MSVC. It is missing some low-level Windows-specific features though.

Is Clang faster than MSVC?

When I switched to both clang and MSVC 64-bit versions, I see MSVC is faster than clang by about 1.5X. On 32-bit toolsets, I saw that MSVC is 2X slower than Clang. This, however, is totally believable because MSVC performance is tracked mostly on the 64-bit toolset.

Will GCC be replaced by Clang?

Clang is designed to provide a frontend compiler that can replace GCC. Apple Inc. (including NeXT later) has been using GCC as the official compiler.

Is GCC compatible with Clang?

Yes, for C code Clang and GCC are compatible (they both use the GNU Toolchain for linking, in fact.) You just have to make sure that you tell clang to create compiled objects and not intermediate bitcode objects. C ABI is well-defined, so the only issue is storage format.


1 Answers

__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) .... 
like image 157
dmg Avatar answered Sep 27 '22 23:09

dmg