Wiem, że pytanie dotyczy GCC, ale pomyślałem, że może przydać się trochę informacji o kompilatorach i innych kompilatorach.
noinline
Atrybut funkcji GCC
jest dość popularny również w innych kompilatorach. Jest wspierany przez co najmniej:
- Clang (sprawdź z
__has_attribute(noinline)
)
- Kompilator Intel C / C ++ (ich dokumentacja jest okropna, ale jestem pewien, że działa na 16.0+)
- Oracle Solaris Studio z powrotem do co najmniej 12.2
- Kompilator ARM C / C ++ z powrotem do co najmniej 4.1
- IBM XL C / C ++ z powrotem do co najmniej 10.1
- TI 8.0+ (lub 7.3+ z --gcc, które zdefiniuje
__TI_GNU_ATTRIBUTE_SUPPORT__
)
Ponadto MSVC obsługuje
__declspec(noinline)
powrót do programu Visual Studio 7.1. Intel prawdopodobnie też to obsługuje (starają się być kompatybilne zarówno z GCC, jak i MSVC), ale nie zadałem sobie trudu, aby to zweryfikować. Składnia jest w zasadzie taka sama:
__declspec(noinline)
static void foo(void) { }
PGI 10.2+ (i prawdopodobnie starsze) wspiera noinline
pragmę, która odnosi się do następnej funkcji:
#pragma noinline
static void foo(void) { }
TI 6.0+ wspiera
FUNC_CANNOT_INLINE
pragmę, która (irytująco) działa inaczej w C i C ++. W C ++ jest podobny do PGI:
#pragma FUNC_CANNOT_INLINE;
static void foo(void) { }
W C jednak nazwa funkcji jest wymagana:
#pragma FUNC_CANNOT_INLINE(foo);
static void foo(void) { }
Cray 6.4+ (i prawdopodobnie wcześniej) przyjmuje podobne podejście, wymagając nazwy funkcji:
#pragma _CRI inline_never foo
static void foo(void) { }
Oracle Developer Studio obsługuje również pragmę, która przyjmuje nazwę funkcji, cofając się co najmniej do Forte Developer 6 , ale pamiętaj, że musi ona nastąpić po deklaracji, nawet w najnowszych wersjach:
static void foo(void);
#pragma no_inline(foo)
W zależności od tego, jak bardzo jesteś oddany, możesz utworzyć makro, które działałoby wszędzie, ale musisz mieć nazwę funkcji, a także deklarację jako argumenty.
Jeśli, OTOH, nie przeszkadza ci coś, co po prostu działa dla większości ludzi, możesz uciec z czymś, co jest trochę bardziej estetyczne i nie wymaga powtarzania się. Oto podejście, które zastosowałem w przypadku Hedley , gdzie obecna wersja
HEDLEY_NEVER_INLINE
wygląda tak:
#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
Jeśli nie chcesz używać Hedley (to pojedynczy nagłówek domeny publicznej / CC0), możesz przekonwertować makra sprawdzające wersję bez zbytniego wysiłku, ale więcej, niż jestem gotów włożyć ☺.