Sorunun GCC ile ilgili olduğunu biliyorum, ancak diğer derleyiciler hakkında da derleyiciler hakkında biraz bilgi sahibi olmanın yararlı olabileceğini düşündüm.
GCC'nin
noinline
işlev özniteliği diğer derleyiciler arasında da oldukça popülerdir. En azından aşağıdakiler tarafından desteklenir:
- Clang (kontrol edin
__has_attribute(noinline)
)
- Intel C / C ++ Derleyici (belgeleri berbat, ancak 16.0+ üzerinde çalıştığından eminim)
- Oracle Solaris Studio, en az 12.2'ye geri döndü
- ARM C / C ++ Derleyici en az 4.1'e geri döndü
- IBM XL C / C ++ en az 10.1'e geri döndü
- TI 8.0+ (veya 7.3+ --gcc ile tanımlanacak
__TI_GNU_ATTRIBUTE_SUPPORT__
)
Ayrıca MSVC, __declspec(noinline)
Visual Studio 7.1'e geri dönmeyi destekler
. Intel muhtemelen bunu da destekliyor (hem GCC hem de MSVC ile uyumlu olmaya çalışıyorlar), ancak bunu doğrulamaya zahmet etmedim. Sözdizimi temelde aynıdır:
__declspec(noinline)
static void foo(void) { }
PGI 10.2+ (ve muhtemelen daha eski), bir noinline
sonraki işlev için geçerli olan bir pragmayı destekler :
#pragma noinline
static void foo(void) { }
TI 6.0+, FUNC_CANNOT_INLINE
(sinir bozucu) C ve C ++ 'da farklı çalışan bir pragmayı destekler
. C ++ 'da, PGI'lara benzer:
#pragma FUNC_CANNOT_INLINE;
static void foo(void) { }
Bununla birlikte, C'de işlev adı gereklidir:
#pragma FUNC_CANNOT_INLINE(foo);
static void foo(void) { }
Cray 6.4+ (ve muhtemelen daha erken), işlev adını gerektiren benzer bir yaklaşımı benimser:
#pragma _CRI inline_never foo
static void foo(void) { }
Oracle Developer Studio ayrıca en azından Forte Developer 6'ya geri dönen işlev adını alan bir pragmayı destekler , ancak son sürümlerde bile bildirimden sonra gelmesi gerektiğini unutmayın :
static void foo(void);
#pragma no_inline(foo)
Kendinize ne kadar adanmış olduğunuza bağlı olarak, her yerde çalışacak bir makro oluşturabilirsiniz, ancak işlev adı ve bağımsız değişken olarak bildirime sahip olmanız gerekir.
OTOH, çoğu insan için işe yarayan bir şeyden memnunsanız, estetik açıdan biraz daha hoş olan ve kendinizi tekrarlamayı gerektirmeyen bir şeyden kurtulabilirsiniz. HEDLEY_NEVER_INLINE'ın mevcut sürümünün
şuna benzediği Hedley için benimsediğim yaklaşım budur :
#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'i kullanmak istemiyorsanız (bu tek bir genel etki alanı / CC0 başlığı), sürüm kontrol makrolarını çok fazla çaba harcamadan, ancak benim ☺ koymaya istekli olduğumdan daha fazlasını dönüştürebilirsiniz.