인라인 함수
Inline function![]() | 이 문서는 갱신할 필요가 있습니다.그 이유는 C++(https://en.cppreference.com/w/cpp/language/inline)에서 인라인으로 변경됨)의 의미입니다. 하여 이 . (2019년 4월) |
C 및 C++ 프로그래밍 언어에서 인라인 함수는 다음 키워드로 수식된 함수입니다. inline
; 이것은 두 가지 목적을 제공합니다.
- 이는 컴파일러가 인라인 확장을 실행함으로써 함수의 본문을 인라인으로 대체하도록 제안하는 컴파일러 명령어로서 기능하며, 즉 각 함수 호출의 주소에 함수 코드를 삽입하여 함수 호출의 오버헤드를 절약합니다.이 점에 있어서, 그것은 와 유사하다.
register
스토리지 클래스 지정자: 마찬가지로 최적화 [1]힌트를 제공합니다. - 두 번째 목적은
inline
링크 동작을 변경하는 것입니다.상세한 것은 복잡합니다.이는 C/C++의 개별 컴파일 + 링크 모델에 의해 필요합니다.특히 함수의 정의(본문)가 컴파일 중에 인라이닝을 허용하기 위해 사용되는 모든 변환 유닛에서 복제되어야 하기 때문에 함수에 외부 링크가 있는 경우 링크 중에 충돌이 발생합니다(외부 심볼의 고유성에 위반됨).C 및 C++(및 GNU C 및 Visual C++ 등의 방언)를 사용하여 [1]이 문제를 해결합니다.
예
안inline
함수는 다음과 같이 C 또는 C++로 쓸 수 있습니다.
인라인 무효 바꾸다(인트 *m, 인트 *n) { 인트 tmp = *m; *m = *n; *n = tmp; }
그런 다음 다음과 같은 문장을 입력합니다.
바꾸다(&x, &y);
다음과 같이 변환할 수 있습니다(컴파일러가 인라인 처리를 결정한 경우, 일반적으로 최적화를 유효하게 할 필요가 있습니다.
인트 tmp = x; x = y; y = tmp;
많은 스왑을 실행하는 정렬 알고리즘을 구현하면 실행 속도가 빨라질 수 있습니다.
표준 지원
C++ 및 C99는 이전 버전인 K&R C 및 C89는 지원하지 않지만inline
함수는 의미론적으로 다릅니다.두 경우 모두,inline
는 강제로 인라인화하지 않습니다.컴파일러는 함수를 전혀 인라인화하지 않을지, 경우에 따라서는 인라인화하지 않을지 자유롭게 선택할 수 있습니다.컴파일러마다 복잡한 함수를 인라인화할 수 있는 정도는 다릅니다.Microsoft Visual C++ 및 GCC 등의 메인스트림 C++ 컴파일러는 적절한 함수를 자동으로 인라인화하는 옵션을 지원합니다.inline
기능들.단, 단순히 생략하고 싶은 말은 생략할 수 있습니다.inline
링커가 다른 변환 유닛의 중복 정의에 대해 불만을 제기하기 때문에 컴파일러가 모든 인라인 결정을 내릴 수 있는 키워드는 불가능합니다.그 이유는inline
함수가 인라인화되어야 한다는 힌트를 컴파일러에 제공할 뿐만 아니라, 함수의 아웃라인 복사를 컴파일러가 생성할지 여부에도 영향을 미칩니다(인라인 함수의 스토리지 클래스 참조).
비표준 내선번호
GNU C는 GNU89를 제공하는 방언의 일부로서inline
C89의 확장으로서.그러나 의미론은 C++와 C99의 의미론과는 다릅니다.C90 모드의 armcc 또한inline
gnu89 및 C99와는 시멘틱스가 다른 비표준 확장자로 사용됩니다.
일부 구현에서는 컴파일러가 함수를 강제로 인라인화하는 수단을 제공합니다.일반적으로 구현 고유의 선언 지정자를 사용합니다.
- Microsoft Visual C++:
__forceinline
- gcc 또는 clang:
__attribute__((always_inline))
또는__attribute__((__always_inline__))
후자는 사용자 정의 매크로와의 경합을 회피하는 데 도움이 됩니다.always_inline
.
이를 무분별하게 사용하면 더 큰 코드(블러딩된 실행 파일)가 생성되고 성능이 최소화되거나 전혀 향상되지 않을 수 있으며 경우에 따라서는 성능이 저하될 수도 있습니다.게다가 인라이닝이 강제되어 있는 경우에도 컴파일러는 모든 상황에서 함수를 인라인화할 수 없습니다.이 경우 gcc와 Visual C++ 모두 경고를 생성합니다.
강제 인라인화는 다음과 같은 경우에 유용합니다.
inline
컴파일러(컴파일러 비용/편익 분석가)가 존중하지 않는 경우- 필요한 퍼포먼스 향상으로 이어지는 결과 표시
코드 이식성을 위해 다음 프리프로세서 디렉티브를 사용할 수 있습니다.
# 정의 _MSC_VER #forceinline__forceinline을 삭제합니다. #el(정의되어 있는 경우) (_GNUC__) #forceinline inline __forceinline __((_항상_forceinline___)) #el(정의되어 있는 경우) (_CLANG__) # _ _ has _ displays ( _ always _ return _ ) #forceinline inline __forceinline __((_항상_forceinline___)) #실패하다 #forceinline inline을 통한 강제 실행 #엔디프 #실패하다 #forceinline inline을 통한 강제 실행 #엔디프
인라인 함수의 스토리지 클래스
static inline
는 모든 C 방언과 C++에서 동일한 효과를 발휘합니다.필요에 따라서, 로컬로 표시되는(의 행외 카피) 기능을 송신합니다.
스토리지 클래스에 관계없이 컴파일러는 다음 명령을 무시할 수 있습니다.inline
모든 C 방언 및 C++에서 함수 호출을 생성합니다.
저장소 클래스의 효과extern
적용 여부에 관계없이inline
기능은[2] C 방언과 C++[3]에 따라 다릅니다.
C99
C99에서 정의된 함수inline
will never 및 정의된 함수extern inline
항상 외부에서 볼 수 있는 기능을 방출합니다.C++와 달리 번역 단위 간에 공유되는 외부 가시 기능을 필요한 경우에만 내보내도록 요구할 수 없습니다.
한다면inline
선언이 뒤섞이다extern inline
선언 또는 부적격 선언(즉, 미적용)을 포함)inline
수식자 또는 스토리지 클래스), 변환 유닛에 정의가 포함되어 있어야 합니다(수식자 없음에 관계없이).inline
, 또는extern inline
외부로 보이는 기능이 출력됩니다.
정의된 함수inline
정의되어 있는 프로그램의 다른 곳에 같은 이름의 함수가 정확히1개 필요합니다.extern inline
또는 한정자를 붙이지 않습니다.전체 프로그램에서 이러한 정의가 여러 개 제공되면 링커는 중복 기호에 대해 불만을 제기합니다.단, 모든 용도를 인라인할 수 있다면 링커는 필요하지 않기 때문에 링커가 반드시 불만을 제기할 필요는 없습니다.하지만 컴파일러는 항상 무시하기 때문에 불평할 수 있습니다.inline
일반적으로 최적화하지 않고 코드가 컴파일된 경우 발생하는 것과 같이 수식자와 함수에 대한 콜을 생성합니다.(이것은, 함수가 모든 장소에 인라인 되어 있을 필요가 있는 경우, 바람직한 동작일 가능성이 있습니다.인라인 되어 있지 않은 경우는 에러가 발생합니다).편리한 방법은 다음과 같이 정의하는 것입니다.inline
헤더 파일에서 기능하고 함수당 하나의 .c 파일을 만듭니다.extern inline
정의와 함께 각 헤더 파일을 포함하는 선언입니다.선언이 include의 전인지 후인지는 중요하지 않습니다.
함수의 모든 용도가 인라인된 경우 도달 불가능한 코드가 최종 실행 파일에 추가되는 것을 방지하기 위해 이러한 모든 .c 파일의 객체 파일을 단일 파일로 저장하는 것이 좋습니다[3].extern inline
정적 라이브러리 파일로 기능합니다.일반적으로ar rcs
개별 객체 파일이 아닌 해당 라이브러리에 링크합니다.따라서 오브젝트 파일을 직접 링크하는 것과 달리 실제로 필요한 오브젝트 파일만 링크되므로 항상 실행 파일에 포함됩니다.단, 라이브러리 파일 뒤에 지정된 오브젝트파일에서 함수에 대한 콜은 링커에 의해 고려되지 않기 때문에 라이브러리 파일은 링커 명령줄의 다른 모든 오브젝트파일 뒤에 지정해야 합니다.에서 온 콜inline
다른 기능에 대한 기능inline
링커에 의해 함수가 자동으로 해결됩니다(s
에 선택권을 주다.ar rcs
이것을 보증합니다).
대체 솔루션은 라이브러리 대신 링크 시간 최적화를 사용하는 것입니다.gcc는 플래그를 제공합니다.-Wl,--gc-sections
모든 기능이 사용되지 않는 섹션을 생략합니다.이는 사용되지 않은 단일의 코드가 포함된 개체 파일의 경우입니다.extern inline
기능.단, 미사용과 관련된 섹션뿐만 아니라 다른 모든 오브젝트파일에서 미사용 섹션도 모두 삭제합니다.extern inline
기능들.(예를 들어 프로그램의 내부 상태를 검사하기 위해 프로그램 자체보다는 프로그래머가 디버거에서 호출해야 하는 실행 파일에 함수를 링크하는 것이 바람직할 수 있습니다.)이 접근방식에서는 단일 .c 파일을 모든 파일과 함께 사용할 수도 있습니다.extern inline
함수당 .c 파일이 1개씩 아닌 함수입니다.그런 다음 파일을 다음과 같이 컴파일해야 합니다.-fdata-sections -ffunction-sections
단, gcc 매뉴얼페이지에서는 "이러한 옵션을 사용하면 큰 이점이 있을 경우에만 사용하세요"라고 경고하고 있습니다.
일부에서는 완전히 다른 접근방식을 권장합니다. 즉, 기능을 다음과 같이 정의하는 것입니다.static inline
대신inline
헤더 파일에 [2]격납되어 있습니다.그러면 도달할 수 없는 코드가 생성되지 않습니다.단, 이 접근법에는 다음과 같은 단점이 있습니다.함수를 여러 변환 유닛에 삽입할 수 없는 경우 중복 코드가 생성됩니다.주소가 달라야 하므로 내보낸 함수 코드를 변환 단위 간에 공유할 수 없습니다.이것은 또 다른 결점입니다.그것은 다음과 같이 정의된 함수의 주소를 취득하는 것입니다.static inline
는 변환 단위마다 다른 값을 생성합니다.그러므로,static inline
함수는 1개의 변환 유닛에서만 사용되는 경우에만 사용해야 합니다.즉, 각 .c 파일에만 적용되며 헤더 파일에는 적용되지 않습니다.
gnu89
gnu89 의미론inline
그리고.extern inline
기본적으로는 [4]C99의 것과 정반대입니다.단, gnu89는 cnu89의 정의를 가능하게 합니다.extern inline
C99에 비적격 함수로 기능합니다.inline
하지 않습니다.[5]따라서 gnu89는extern inline
재정의하지 않으면 C99와 같다inline
, 및 gnu89inline
C99와 같다extern inline
즉, gnu89에서 정의된 함수입니다.inline
will always 및 정의된 함수extern inline
외부에서 볼 수 있는 기능을 방출하지 않습니다.그 이유는 다음과 같이 정의하면 스토리지가 예약되지 않는 변수와 일치하기 때문입니다.extern
그리고 항상 정의되지 않은 경우.이와는 대조적으로 C99의 근거는 다음과 같이 사용할 경우 놀라운 결과를 얻을 수 있다는 것이다.inline
는, 그 이름이 나타내는 것과 달리, 항상 함수의 비인쇄 버전을 방출하는 부작용이 있습니다.
인라인된 함수에 대해 정확히 하나의 외부 가시적인 함수 인스턴스를 제공할 필요성과 도달 불가능한 코드의 문제에 대한 C99에 대한 언급은 gnu89에도 적용됩니다.
gcc는 버전 4.2까지 사용.gnu89inline
시멘틱스-std=c99
를 명시적으로 [6]지정했습니다.버전 [5]5에서는 gcc가 gnu89에서 gnu11 방언으로 전환되어 C99가 유효하게 되었습니다.inline
디폴트로는 semantics 입니다.대신 gnu89 시멘틱스를 사용하려면 다음 중 하나를 사용하여 명시적으로 활성화해야 합니다.-std=gnu89
또는 인라인에만 영향을 미치기 위해-fgnu89-inline
또는 를 추가함으로써gnu_inline
모든 사람에게 귀속되다inline
선언을 합니다.C99의 시멘틱스를 확보하려면-std=c99
,-std=c11
,-std=gnu99
또는-std=gnu11
(없음)-fgnu89-inline
)[3]를 사용할 수 있습니다.
C++
C++에서 정의된 함수inline
는 필요에 따라 변환 유닛 간에 공유되는 기능을 내보냅니다.통상은 변환 유닛이 필요한 오브젝트 파일의 공통 섹션에 추가합니다.함수는 어디에서나 동일한 정의를 가져야 합니다.inline
한정자C++에서는extern inline
와 같다inline
C++ 어프로치의 근거는, 도달 불능 코드를 제거하기 위한 특별한 예방 조치를 취할 필요가 없고, 통상의 함수와 같이, 그것이 프로그래머에게 있어서 가장 편리한 방법이라고 하는 것입니다.extern
지정 여부를 지정합니다.
그inline
한정자는 클래스 정의의 일부로 정의된 함수에 자동으로 추가됩니다.
암CC
C90 모드의 armcc는extern inline
그리고.inline
C++와 동일한 의미: 이러한 정의는 필요에 따라 변환 유닛 간에 공유되는 함수를 내보냅니다.C99 모드에서는extern inline
항상 기능을 내보내지만 C++와 마찬가지로 변환 유닛 간에 공유됩니다.따라서 동일한 함수를 정의할 수 있습니다.extern inline
다른 번역 단위로.[7]이것은, 복수의 Unix C 컴파일러의[8] 종래의 동작과 일치합니다.extern
초기화되지 않은 글로벌 변수의 정의입니다.
제약 사항
주소 가져오기inline
함수에는 어떤 경우에도 해당 함수의 비인라인 복사를 내보내려면 코드가 필요합니다.
C99에서는inline
또는extern inline
함수는 액세스 할 수 없습니다.static
글로벌 변수 또는 비변수 정의const
static
로컬 변수 const static
로컬 변수는 함수가 인라인되었는지 또는 콜이 발신되었는지 여부에 따라 다른 변환 단위로 다른 객체가 될 수도 있고 아닐 수도 있고 아닐 수도 있습니다.오직.static inline
정의는 제한 없이 내부 링크를 사용하여 식별자를 참조할 수 있습니다.이러한 ID는 변환 유닛마다 다른 오브젝트입니다.C++에서는 둘 다const
및 비-const
static
로컬은 허용되며 모든 변환 유닛에서 동일한 객체를 참조합니다.
다음과 같은 경우 gcc는 인라인 기능을[3] 할 수 없습니다.
- 그들은 변종이다.
- 사용하다
alloca
- 계산하여 사용하다
goto
- 로컬이 아닌 사용
goto
- 중첩 함수 사용
- 사용하다
setjmp
- 사용하다
__builtin_longjmp
- 사용하다
__builtin_return
, 또는 - 사용하다
__builtin_apply_args
MSDN 의 Microsoft 사양에 근거해, MS Visual C++ 는 인라인 할 수 없습니다(MS Visual C++ 는,__forceinline
)의 경우
- 함수 또는 함수 호출자는 /Ob0(디버깅 빌드의 기본 옵션)으로 컴파일됩니다.
- 함수와 발신자는 다른 유형의 예외 처리(한쪽에서는 C++ 예외 처리, 다른쪽에서는 구조화된 예외 처리)를 사용합니다.
- 함수에는 변수 인수 목록이 있습니다.
- 함수는 /Og, /Ox, /O1 또는 /O2로 컴파일되지 않는 한 인라인 어셈블리를 사용합니다.
- 함수는 재귀적이며 다음을 수반하지 않습니다.
#pragma inline_recursion(on)
. 플러그마를 사용하면 재귀 함수는 기본 깊이인 16콜까지 인라인 처리됩니다.인라이닝 깊이를 줄이려면inline_depth
플러그마 - 함수는 가상이며 가상으로 호출됩니다.가상 기능에의 다이렉트 콜을 인라인 할 수 있습니다.
- 프로그램이 함수의 주소를 가져오고 함수에 대한 포인터를 통해 호출이 이루어집니다.주소를 취득한 기능에의 다이렉트 콜은, 인라인 할 수 있습니다.
- 이 기능은 나체로 표시되기도 합니다.
__declspec
수식어
문제
인라인 확장에 관한 일반적인 문제 외에 (인라인 확장에 대한 영향 참조),inline
언어 기능으로서의 기능은 여러 가지 이유로 보이는 것만큼 가치가 없을 수 있습니다.
- 컴파일러는 특정 함수를 삽입해야 하는지 여부를 결정하는 데 인간보다 더 나은 위치에 있는 경우가 많습니다.때때로 컴파일러는 프로그래머가 나타내는 함수만큼 많은 함수를 인라인화할 수 없을 수 있습니다.
- 주의할 점은 (의) 코드가
inline
function)이 클라이언트에 공개됩니다(발신 기능). - 기능이 진화함에 따라 이전에는 없었던 인라인에 적합하거나 더 이상 이전의 인라인에 적합하지 않을 수 있습니다.기능의 인라인 또는 언인라인은 매크로로 변환하거나 매크로에서 변환하는 것보다 간단하지만 유지보수가 추가로 필요하기 때문에 일반적으로는 이점이 거의 없습니다.
- 네이티브 C 기반 컴파일 시스템에서 확산에 사용되는 인라인 함수는 본문의 중간 표현이 각 콜 사이트에 복사되기 때문에 컴파일 시간을 늘릴 수 있습니다.
- 의 사양
inline
C99 에서는, 함수의 외부 정의가 1개만 필요합니다(어디서 사용되고 있는 경우).이러한 정의가 프로그래머에 의해 제공되지 않으면 링커 오류가 발생하기 쉽습니다.이 문제는 최적화가 꺼진 상태에서 발생할 수 있으며 일반적으로 인라인화가 방지됩니다.한편, 정의를 추가하는 것은, 프로그래머가 신중하게 피하지 않는 경우, 링크 시간 최적화를 위해 라이브러리에 배치하거나, 또는 링크 시간 최적화를 사용하는 것으로써, 도달 불능의 코드를 일으킬 수 있습니다.static inline
. - C++ 에서는, 다음과 같이 정의할 필요가 있습니다.
inline
이 기능을 사용하는 모든 모듈(정보 유닛)에서 기능을 수행하지만 일반 기능은 단일 모듈에서만 정의해야 합니다.그렇지 않으면 단일 모듈을 다른 모든 모듈과 독립적으로 컴파일할 수 없습니다.컴파일러에 따라서는 인라인을 사용할 수 없는 모듈별로 각 오브젝트 파일에 함수 코드의 복사본이 포함될 수 있습니다. - 임베디드 소프트웨어에서는 "pragma" 문과 같은 특별한 컴파일러 명령을 사용하여 특정 코드 섹션에 특정 함수를 배치해야 하는 경우가 많습니다.어떤 메모리 세그먼트의 함수가 다른 메모리 세그먼트의 함수를 호출해야 하는 경우가 있으며, 호출된 함수의 인라이닝이 발생할 경우 호출된 함수의 코드가 있으면 안 되는 세그먼트에 포함될 수 있습니다.예를 들어 고성능 메모리세그먼트는 코드 공간이 매우 한정되어 있을 수 있습니다.이러한 공간에 속하는 함수가 고성능 섹션에 없는 다른 큰 함수를 호출하여 호출된 함수가 부적절하게 삽입되면 고성능 메모리세그먼트의 코드 공간이 부족해질 수 있습니다.이러한 이유로 기능이 인라인화되지 않도록 하는 것이 필요할 수 있습니다.
견적서
- "인라인 지정자가 있는 함수 선언 [ . . . ]은 인라인 함수를 선언합니다.인라인 지정자는 콜 포인트에서의 함수 본체의 인라인 치환이 통상의 함수콜 메커니즘보다 우선함을 실장에 나타냅니다.콜 포인트에서 이 인라인 치환을 실행하기 위해 구현이 필요한 것은 아닙니다.다만, 이 인라인 치환을 생략해도, 7.1.2 로 정의되고 있는 인라인 기능의 다른 룰은 계속 존중됩니다」
- - ISO/IEC 14882:2011, 현행 C++ 표준, 섹션 7.1.2
- "인라인 함수 지정자로 선언된 함수는 인라인 함수입니다.[ . . ] 함수를 인라인 함수로 하는 것은 함수에 대한 호출을 가능한 한 빠르게 하는 것을 의미합니다.이러한 제안이 효과적인 범위는 구현에 정의되어 있습니다(각주: 예를 들어, 실장에서는 인라인 치환을 실행하지 않거나 인라인 선언 범위 내의 콜에 대해서만 인라인 치환을 실행할 수 있습니다).
- " . . . ] 인라인 정의는 함수에 대한 외부 정의를 제공하지 않으며 다른 변환 단위로 외부 정의를 금지하지 않습니다.인라인 정의는 외부 정의 대신 사용할 수 있습니다.외부 정의는 변환자가 같은 변환 유닛에서 함수에 대한 콜을 구현하기 위해 사용할 수 있습니다.함수에 대한 콜이 인라인 정의를 사용하는지 외부 정의를 사용하는지는 지정되지 않았습니다."
- - ISO 9899:1999(E), C99 표준, 섹션 6.7.4
「 」를 참조해 주세요.
레퍼런스
- ^ a b Meyers, Randy (July 1, 2002). "The New C: Inline Functions".
{{cite journal}}
:Cite 저널 요구 사항journal=
(도움말) - ^ a b "Inline Functions in C".
- ^ a b c d "Using the GNU Compiler Collection (GCC): Inline".
- ^ "Josef "Jeff" Sipek » GNU inline vs. C99 inline".
- ^ a b "Porting to GCC 5 - GNU Project".
- ^ "Ian Lance Taylor - Clean up extern inline".
- ^ "Documentation – Arm Developer".
- ^ gcc 매뉴얼페이지, 설명
-fno-common
- JANA, DEBASISH (1 January 2005). C++ AND OBJECT-ORIENTED PROGRAMMING PARADIGM. PHI Learning Pvt. Ltd. ISBN 978-81-203-2871-6.
- Sengupta, Probal (1 August 2004). Object-Oriented Programming: Fundamentals And Applications. PHI Learning Pvt. Ltd. ISBN 978-81-203-1258-6.
- Svenk, Goran (2003). Object-oriented Programming: Using C++ for Engineering and Technology. Cengage Learning. ISBN 0-7668-3894-3.
- Balagurusamy (2013). Object Oriented Programming with C++. Tata McGraw-Hill Education. ISBN 978-1-259-02993-6.
- Kirch-Prinz, Ulla; Prinz, Peter (2002). A Complete Guide to Programming in C++. Jones & Bartlett Learning. ISBN 978-0-7637-1817-6.
- Conger, David (2006). Creating Games in C++: A Step-by-step Guide. New Riders. ISBN 978-0-7357-1434-2.
- Skinner, M. T. (1992). The Advanced C++ Book. Silicon Press. ISBN 978-0-929306-10-0.
- Love (1 September 2005). Linux Kernel Development. Pearson Education. ISBN 978-81-7758-910-8.
- DEHURI, SATCHIDANANDA; JAGADEV, ALOK KUMAR; RATH, AMIYA KUMAR (8 May 2007). OBJECT-ORIENTED PROGRAMMING USING C++. PHI Learning Pvt. Ltd. ISBN 978-81-203-3085-6.