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
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.
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.
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.
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.
__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) ....
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With