Обнаружить gcc в отличие от msvc/clang с макросом
Я работаю над проектом, который был построен как с gcc, так и с msvc. Недавно мы начали строить с помощью clang.
В коде есть некоторые части, где выполняются действия, специфичные для платформы:
#ifndef _WIN32
// ignore this in msvc
#endif
Поскольку gcc ранее была единственной не-оконной сборкой, это было эквивалентно утверждению "делать это только для gcc". Но теперь это означает "делать это только для gcc и clang".
Однако есть еще ситуации, когда я хотел бы обработать что-то специально для gcc, а не для clang. Есть простой и надежный способ обнаружения gcc, т.е.
#ifdef ???
// do this *only* for gcc
#endif
Ответы
Ответ 1
__GNUC__
__GNUC_MINOR__
__GNUC_PATCHLEVEL__
Эти макросы определяются всеми компиляторами GNU, которые используют препроцессор C: C, С++, Objective-C и Fortran. Их значениями являются основная версия, младшая версия и уровень исправления компилятора, как целочисленные константы. Например, GCC 3.2.1 определит __GNUC__ до 3, __GNUC_MINOR__ до 2 и __GNUC_PATCHLEVEL__ до 1. Эти макросы также определены, если вы вызываете препроцессор напрямую.
также:
__GNUG__
Компилятор GNU С++ определяет это. Тестирование эквивалентно тестированию (__GNUC__ & __cplusplus).
Источник
По-видимому, clang
тоже использует их. Однако он также определяет:
__clang__
__clang_major__
__clang_minor__
__clang_patchlevel__
Итак, вы можете сделать:
#ifdef __GNUC__
#ifndef __clang__
...
Или даже лучше (обратите внимание на порядок):
#if defined(__clang__)
....
#elif defined(__GNUC__) || defined(__GNUG__)
....
#elif defined(_MSC_VER)
....
Ответ 2
С Boost это становится очень простым:
#include <boost/predef.h>
#ifdef BOOST_COMP_GNUC
// do this *only* for gcc
#endif
(кредит rubenvb, который упомянул об этом в комментарии, и Alberto M для добавления include)
Ответ 3
__GNUG__
может быть вашим лучшим выбором - см. здесь. Это тесты для GNU С++ специально, а не только компилятор GNU C/С++/FORTRAN за __GNUC__
- то есть "эквивалент тестирования (__GNUC__ && __cplusplus)
".
Ответ 4
Я использую это определение:
#define GCC_COMPILER (defined(__GNUC__) && !defined(__clang__))
И протестируйте его:
#if GCC_COMPILER
...
#endif