Я знаю, что вопрос касается GCC, но я подумал, что было бы полезно получить некоторую информацию о компиляторах и других компиляторах.
noinline
Атрибут функции GCC также
очень популярен среди других компиляторов. Его поддерживают как минимум:
- Clang (сверьтесь с
__has_attribute(noinline)
)
- Компилятор Intel C / C ++ (их документация ужасна, но я уверен, что он работает на 16.0+)
- Oracle Solaris Studio возвращается как минимум к версии 12.2
- Компилятор ARM C / C ++ вернулся как минимум к версии 4.1
- IBM XL C / C ++ вернулся как минимум к 10.1
- TI 8.0+ (или 7.3+ с --gcc, который определит
__TI_GNU_ATTRIBUTE_SUPPORT__
)
Кроме того, MSVC поддерживает возврат
__declspec(noinline)
к Visual Studio 7.1. Intel, вероятно, тоже поддерживает это (они пытаются быть совместимыми как с GCC, так и с MSVC), но я не удосужился проверить это. Синтаксис в основном такой же:
__declspec(noinline)
static void foo(void) { }
PGI 10.2+ (и, вероятно, старше) поддерживает noinline
прагму, которая применяется к следующей функции:
#pragma noinline
static void foo(void) { }
TI 6.0+ поддерживает
FUNC_CANNOT_INLINE
прагму, которая (что досадно) по-разному работает в C и C ++. В C ++ он похож на PGI:
#pragma FUNC_CANNOT_INLINE;
static void foo(void) { }
В C, однако, имя функции обязательно:
#pragma FUNC_CANNOT_INLINE(foo);
static void foo(void) { }
Cray 6.4+ (и, возможно, ранее) использует аналогичный подход, требуя имя функции:
#pragma _CRI inline_never foo
static void foo(void) { }
Oracle Developer Studio также поддерживает прагму, которая принимает имя функции, по крайней мере, в Forte Developer 6 , но обратите внимание, что она должна идти после объявления, даже в последних версиях:
static void foo(void);
#pragma no_inline(foo)
В зависимости от того, насколько вы преданы своему делу, вы можете создать макрос, который будет работать везде, но вам нужно будет иметь имя функции, а также объявление в качестве аргументов.
Если, OTOH, вас устраивает то, что подходит большинству людей, вам может сойдет с рук то, что немного более эстетично и не требует повторения. Это подход, который я использовал для Hedley , где текущая версия
HEDLEY_NEVER_INLINE
выглядит так:
#if \
HEDLEY_GNUC_HAS_ATTRIBUTE(noinline,4,0,0) || \
HEDLEY_INTEL_VERSION_CHECK(16,0,0) || \
HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
HEDLEY_TI_VERSION_CHECK(8,0,0) || \
(HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
# define HEDLEY_NEVER_INLINE __attribute__((__noinline__))
#elif HEDLEY_MSVC_VERSION_CHECK(13,10,0)
# define HEDLEY_NEVER_INLINE __declspec(noinline)
#elif HEDLEY_PGI_VERSION_CHECK(10,2,0)
# define HEDLEY_NEVER_INLINE _Pragma("noinline")
#elif HEDLEY_TI_VERSION_CHECK(6,0,0)
# define HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
#else
# define HEDLEY_NEVER_INLINE HEDLEY_INLINE
#endif
Если вы не хотите использовать Hedley (это единственный общедоступный заголовок / CC0), вы можете преобразовать макросы проверки версии без особых усилий, но больше, чем я готов вложить ☺.