Detect Gcc as Opposed to Msvc/Clang with MACro

Detect gcc as opposed to msvc / clang with macro

__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)
....

Recognizing clang, gcc, and tcc by implementation-defined macros

Use __TINYC__ to detect tcc1.

Detection of gcc and clang is explained in this StackOverflow question: Detect gcc as opposed to msvc / clang with macro


1 (Quoted from: http://bellard.org/tcc/tcc-doc.html#SEC9)

__TINYC__ is a predefined macro to 1 to indicate that you use TCC.

What predefined macro can I use to detect clang?

Found the answer using strings + grep :

$ strings /usr/bin/clang | grep __ | grep -i clang
__clang__

What are the deviations between preprocessors of GCC/CLANG vs MSVC?

Microsoft's Visual C++ preprocessor has known compliance issues.

They have rewritten the preprocessor but the old one is enabled by default. To enable the, hopefully more compliant one select this option:

/experimental:preprocessor

Starting with the Visual Studio 2017 15.8 Preview 3 release.

I ran the macros using the option: /experimental:preprocessor on the latest released version 15.8.9, with the following results:

: empty
a.b. : not empty
A : not empty
() : not empty
int()(more) : not empty
(int) : not empty
foo bar : not empty
* : not empty

: empty
1, 2 : not empty
1. : not empty
.1 : not empty
1, : not empty
(int)(float) : not empty
() this : not empty
() is, () not () empty() : not empty
, notempty : not empty
(), notempty : not empty
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, ) : not empty

The erroneous "empty" is now "not empty" and is consistent with GCC and Clang' preprocessors.

What predefined macro can be used to detect debug build with clang?

If you look at the project settings of your IDE, you will see that those macros are actually manually defined there, they are not automatically defined by the compiler. In fact, there is no way for the compiler to actually know if it's building a "debug" or "release", it just builds depending on the flags provided to it by the user (or IDE).

You have to make your own macros and define them manually, just like the IDE does for you when creating the projects.

clang behaves differently than msvc++ and gcc

When you use the subscript operator on a std::map<K, T> it finds the element and, if the element is not present, inserts one. Thus, depending on whether the left-hand side or the right-hand side of

gcctest[t] = get(t);

is evaluated first, you'll get different results. The result of the program is, however, just unspecified.

Distinguish between Clang CL and MSVC CL

The macro you're looking for is __clang__.

Note that the regular Clang (not only Clang-CL) also defines it, so you want to check for both __clang__ and _MSC_VER at the same time.



Related Topics



Leave a reply



Submit