[c] gcc에게 함수를 인라인하지 말라고 어떻게 말할 수 있습니까?

소스 파일 에이 작은 기능이 있다고 가정 해보십시오.

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))
{
}

외부 사용을 위해 함수를 선언 할 때와 함수를 작성할 때 둘 다 사용해야합니다.