Я знаю, що питання стосується GCC, але я подумав, що може бути корисним мати деяку інформацію про компілятори та інших компіляторів.
noinline
Функціональний атрибут GCC
досить популярний і у інших компіляторів. Він підтримується щонайменше:
- Кланг (перевірити
__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+ (і, можливо, старші) підтримує a 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), ви можете конвертувати макроси для перевірки версій без особливих зусиль, але більше, ніж я готовий вкласти ☺.