Tôi biết câu hỏi là về GCC, nhưng tôi nghĩ nó có thể hữu ích khi có một số thông tin về trình biên dịch khác.
noinline
Thuộc tính hàm của GCC
cũng khá phổ biến với các trình biên dịch khác. Nó được hỗ trợ bởi ít nhất:
- Clang (kiểm tra với
__has_attribute(noinline)
)
- Trình biên dịch Intel C / C ++ (tài liệu của họ rất tệ, nhưng tôi chắc chắn rằng nó hoạt động trên 16.0+)
- Oracle Solaris Studio trở lại ít nhất 12.2
- Trình biên dịch ARM C / C ++ trở lại ít nhất 4.1
- IBM XL C / C ++ trở lại ít nhất 10.1
- TI 8.0+ (hoặc 7.3+ với --gcc, sẽ xác định
__TI_GNU_ATTRIBUTE_SUPPORT__
)
Ngoài ra, MSVC hỗ trợ
__declspec(noinline)
quay lại Visual Studio 7.1. Intel cũng có thể hỗ trợ nó (họ cố gắng tương thích với cả GCC và MSVC), nhưng tôi không bận tâm để xác minh điều đó. Cú pháp về cơ bản là giống nhau:
__declspec(noinline)
static void foo(void) { }
PGI 10.2+ (và có thể cũ hơn) hỗ trợ một noinline
pragma áp dụng cho chức năng tiếp theo:
#pragma noinline
static void foo(void) { }
TI 6.0+ hỗ trợ một
FUNC_CANNOT_INLINE
pragma mà (thật khó chịu) hoạt động khác nhau trong C và C ++. Trong C ++, nó tương tự như PGI:
#pragma FUNC_CANNOT_INLINE;
static void foo(void) { }
Trong C, tuy nhiên, tên hàm được yêu cầu:
#pragma FUNC_CANNOT_INLINE(foo);
static void foo(void) { }
Cray 6.4+ (và có thể sớm hơn) có cách tiếp cận tương tự, yêu cầu tên hàm:
#pragma _CRI inline_never foo
static void foo(void) { }
Oracle Developer Studio cũng hỗ trợ một pragma lấy tên hàm, quay trở lại ít nhất là Forte Developer 6 , nhưng lưu ý rằng nó cần phải xuất hiện sau khai báo, ngay cả trong các phiên bản gần đây:
static void foo(void);
#pragma no_inline(foo)
Tùy thuộc vào mức độ tận tâm của bạn, bạn có thể tạo một macro hoạt động ở mọi nơi, nhưng bạn sẽ cần phải có tên hàm cũng như khai báo làm đối số.
Nếu, OTOH, bạn ổn với thứ gì đó chỉ phù hợp với hầu hết mọi người, bạn có thể thoát khỏi thứ gì đó có tính thẩm mỹ hơn một chút và không cần phải lặp lại. Đó là cách tiếp cận tôi đã thực hiện cho Hedley , nơi phiên bản hiện tại của
HEDLEY_NEVER_INLINE
trông giống như:
#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
Nếu bạn không muốn sử dụng Hedley (đó là một tên miền công cộng / tiêu đề Muff), bạn có thể chuyển đổi các macro kiểm tra phiên bản mà không cần quá nhiều nỗ lực, nhưng nhiều hơn tôi sẵn sàng đưa vào.