Подтвердить что ты не робот

Обнаружить 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
4b9b3361

Ответ 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