소스 파일 에이 작은 기능이 있다고 가정 해보십시오.
static void foo() {}
바이너리의 최적화 된 버전을 빌드하지만이 기능을 최적화하지 않기 위해 인라인하지 않으려 고합니다. 인라인을 방지하기 위해 소스 코드에 추가 할 수있는 매크로가 있습니까?
답변
gcc
-특정 noinline
속성을 원합니다 .
이 함수 속성은 함수가 인라인으로 간주되지 않도록합니다. 함수에 부작용이없는 경우 함수 호출이 활성화되어 있지만 인라인 이외의 최적화를 통해 함수 호출을 최적화 할 수 있습니다. 이러한 통화가 최적화되지 않도록하려면
asm ("");
다음과 같이 사용하십시오.
void __attribute__ ((noinline)) foo()
{
...
}
답변
GCC에는
-fno-inline-small-functions
gcc를 호출 할 때 사용하십시오. 그러나 부작용은 다른 모든 작은 함수들도 인라인되지 않는다는 것입니다.
답변
이를 수행하는 휴대용 방법은 포인터를 통해 함수를 호출하는 것입니다.
void (*foo_ptr)() = foo;
foo_ptr();
이것은 분기마다 다른 지침을 생성하지만 목표가 아닐 수도 있습니다. 다음 중 좋은 점을 제시합니다. 여기서 목표 는 무엇 입니까?
답변
질문은 GCC에 관한 것임을 알고 있지만 다른 컴파일러에도 컴파일러에 대한 정보가 있으면 도움이 될 것이라고 생각했습니다.
GCC의
noinline
함수 속성은 다른 컴파일러에서도 널리 사용됩니다. 최소한 다음에 의해 지원됩니다.
- 클랑 (으로 확인
__has_attribute(noinline)
) - Intel C / C ++ Compiler (그들의 문서는 끔찍하지만 16.0 이상에서 작동한다고 확신합니다)
- Oracle Solaris Studio를 12.2 이상으로 다시
- 4.1 이상으로 ARM C / C ++ 컴파일러
- IBM XL C / C ++를 10.1 이상으로 되돌림
- TI 8.0 이상 (또는 –gcc를 사용하는 7.3 이상
__TI_GNU_ATTRIBUTE_SUPPORT__
)
또한 MSVC는 __declspec(noinline)
Visual Studio 7.1로 다시 지원합니다
. 인텔은 아마도 그것을 지원할 것입니다 (GCC와 MSVC 모두와 호환하려고 시도하지만). 문법은 기본적으로 같습니다 :
__declspec(noinline)
static void foo(void) { }
PGI 10.2+ (및 이전 버전)는 noinline
다음 기능에 적용되는 pragma를 지원 합니다.
#pragma noinline
static void foo(void) { }
TI 6.0+는 FUNC_CANNOT_INLINE
C와 C ++에서 다르게 작동 하는 pragma를 지원합니다
. 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 로 돌아가는 pragma를 지원 하지만 , 최신 버전에서도 선언 뒤에 와야 합니다.
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 헤더)를 사용하지 않으려는 경우 너무 많은 노력없이 버전 확인 매크로를 변환 할 수 있지만 ☺에 넣을 수있는 것 이상입니다.
답변
에 대한 컴파일러 오류가 발생 __attribute__((noinline))
하면 다음을 시도해보십시오.
noinline int func(int arg)
{
....
}
답변
static __attribute__ ((noinline)) void foo()
{
}
이것이 나를 위해 일한 것입니다.
답변
noinline
속성을 사용하십시오 .
int func(int arg) __attribute__((noinline))
{
}
외부 사용을 위해 함수를 선언 할 때와 함수를 작성할 때 둘 다 사용해야합니다.
