인라인 함수(C++)Inline Functions (C++)

클래스 선언의 본문에 정의된 함수는 인라인 함수입니다.A function defined in the body of a class declaration is an inline function.

예제Example

다음 클래스 선언에서 Account 생성자는 인라인 함수입니다.In the following class declaration, the Account constructor is an inline function. 멤버 함수 GetBalance , 및은 (는) Deposit Withdraw 로 지정 되지 inline 않지만 인라인 함수로 구현할 수 있습니다.The member functions GetBalance, Deposit, and Withdraw aren't specified as inline but can be implemented as inline functions.

// Inline_Member_Functions.cpp
class Account
{
public:
    Account(double initial_balance) { balance = initial_balance; }
    double GetBalance();
    double Deposit( double Amount );
    double Withdraw( double Amount );
private:
    double balance;
};

inline double Account::GetBalance()
{
    return balance;
}

inline double Account::Deposit( double Amount )
{
    return ( balance += Amount );
}

inline double Account::Withdraw( double Amount )
{
    return ( balance -= Amount );
}
int main()
{
}

참고

클래스 선언에서 함수는 키워드를 사용 하지 않고 선언 되었습니다 inline .In the class declaration, the functions were declared without the inline keyword. inline 키워드는 클래스 선언에서 지정할 수 있습니다. 결과는 동일 합니다.The inline keyword can be specified in the class declaration; the result is the same.

주어진 인라인 멤버 함수는 모든 컴파일 단위에서 동일한 방식으로 선언되어야 합니다.A given inline member function must be declared the same way in every compilation unit. 이 제한 사항으로 인해 인라인 함수는 마치 인스턴스화된 함수처럼 동작합니다.This constraint causes inline functions to behave as if they were instantiated functions. 또한 인라인 함수의 정의는 정확히 하나만 있어야 합니다.Additionally, there must be exactly one definition of an inline function.

클래스 멤버 함수는 해당 함수에 대 한 정의에 지정자를 포함 하지 않는 한 기본적으로 외부 링크로 설정 inline 됩니다.A class member function defaults to external linkage unless a definition for that function contains the inline specifier. 앞의 예제에서는 지정자를 사용 하 여 이러한 함수를 명시적으로 선언 하지 않아도 되는 것을 보여 줍니다 inline .The preceding example shows that you don't have to declare these functions explicitly with the inline specifier. inline 함수 정의에서를 사용 하면 해당 함수가 인라인 함수가 됩니다.Using inline in the function definition causes it to be an inline function. 그러나 함수를 호출한 후에는 함수를 다시 선언할 수 없습니다 inline .However, it's not allowed to redeclare a function as inline after a call to that function.

inline, __inline, __forceinlineinline, __inline, and __forceinline

inline 및 지정자는 함수가 __inline 호출 되는 각 장소에 함수 본문의 복사본을 삽입 하도록 컴파일러에 지시 합니다.The inline and __inline specifiers instruct the compiler to insert a copy of the function body into each place the function is called.

인라인 확장 또는 인라이닝이라고 하는 삽입은 컴파일러의 비용 혜택 분석에서 유용한 것으로 표시 되는 경우에만 발생 합니다.The insertion, called inline expansion or inlining, occurs only if the compiler's cost-benefit analysis shows it's worthwhile. 인라인 확장은 보다 큰 코드 크기의 잠재적 비용으로 함수 호출 오버 헤드를 최소화 합니다.Inline expansion minimizes the function-call overhead at the potential cost of larger code size.

__forceinline 키워드는 비용 혜택 분석을 재정의 하 고 대신 프로그래머의 판단에 의존 합니다.The __forceinline keyword overrides the cost-benefit analysis and relies on the judgment of the programmer instead. 을 사용할 때는 주의 해야 __forceinline 합니다.Exercise caution when using __forceinline. 무분별를 사용 __forceinline 하면 성능이 크게 향상 되거나 경우에 따라 더 큰 실행 파일의 페이징이 증가 하 여 성능이 저하 될 수 있습니다.Indiscriminate use of __forceinline can result in larger code with only marginal performance gains or, in some cases, even performance losses (because of the increased paging of a larger executable, for example).

인라인 함수를 사용하면 함수 호출과 연관된 오버헤드가 제거되어 프로그램 속도가 더 빨라질 수 있습니다.Using inline functions can make your program faster because they eliminate the overhead associated with function calls. 인라인으로 확장된 함수에는 일반 함수에 사용할 수 없는 코드 최적화가 적용됩니다.Functions expanded inline are subject to code optimizations not available to normal functions.

컴파일러는 인라인 확장 옵션과 키워드를 제안으로 처리합니다.The compiler treats the inline expansion options and keywords as suggestions. 함수가 인라인 될 수 있는 것은 아닙니다.There's no guarantee that functions will be inlined. 컴파일러가 키워드를 사용 하는 경우에도 특정 함수를 인라인 하도록 강제할 수 없습니다 __forceinline .You can't force the compiler to inline a particular function, even with the __forceinline keyword. 를 사용 하 여 컴파일할 때 /clr 컴파일러는 함수에 적용 되는 보안 특성이 있는 경우 함수를 인라인 하지 않습니다.When compiling with /clr, the compiler won't inline a function if there are security attributes applied to the function.

inline 키워드는 c + + 에서만 사용할 수 있습니다.The inline keyword is available only in C++. __inline__forceinline 키워드는 c 및 c + +에서 사용할 수 있습니다.The __inline and __forceinline keywords are available in both C and C++. 이전 버전과의 호환성을 위해 _inline_forceinline 은에 대 한 동의어이 __inline 고, __forceinline 컴파일러 옵션 /Za ( 사용 안 함 언어 확장 사용 안 함 을 지정 하지 않으면입니다.For compatibility with previous versions, _inline and _forceinline are synonyms for __inline, and __forceinline unless compiler option /Za (Disable language extensions) is specified.

inline 키워드는 인라인 확장의 기본 설정에 대해 컴파일러에 지시 합니다.The inline keyword tells the compiler that inline expansion is preferred. 그러나 컴파일러는 함수의 별도 인스턴스를 만들고(인스턴스화) 인라인으로 코드를 삽입하는 대신 표준 호출 링크를 만들 수 있습니다.However, the compiler can create a separate instance of the function (instantiate) and create standard calling linkages instead of inserting the code inline. 이러한 동작이 발생할 수 있는 두 가지 경우는 다음과 같습니다.Two cases where this behavior can happen are:

  • 재귀 함수.Recursive functions.

  • 변환 단위의 다른 위치에서 포인터를 통해 참조되는 함수.Functions that are referred to through a pointer elsewhere in the translation unit.

이러한 이유는 컴파일러의 재량에 따라 다른 것 처럼인라인 처리에 방해가 될 수 있습니다. inline 함수가 인라인 되도록 하려면 지정자에 종속 되지 않아야 합니다.These reasons may interfere with inlining, as may others, at the discretion of the compiler; you shouldn't depend on the inline specifier to cause a function to be inlined.

일반 함수와 마찬가지로 인라인 함수에서 인수 계산에 대 한 순서는 정의 되어 있지 않습니다.As with normal functions, there's no defined order for argument evaluation in an inline function. 실제로 일반적인 함수 호출 프로토콜을 사용 하 여 전달 되는 경우 인수 계산 순서와 다를 수 있습니다.In fact, it could be different from the argument evaluation order when passed using the normal function-call protocol.

/Ob컴파일러 최적화 옵션은 인라인 함수 확장이 실제로 발생 하는지 여부를 확인 하는 데 도움이 됩니다.The /Ob compiler optimization option helps to determine whether inline function expansion actually occurs.

/LTCG는 소스 코드에서 요청 되었는지 여부에 관계 없이 크로스 모듈을 인라인 합니다./LTCG does cross-module inlining whether it's requested in source code or not.

예제 1Example 1

// inline_keyword1.cpp
// compile with: /c
inline int max( int a , int b ) {
   if( a > b )
      return a;
   return b;
}

클래스의 멤버 함수는 키워드를 사용 하 여 인라인으로 선언 inline 하거나 클래스 정의 내에 함수 정의를 배치할 수 있습니다.A class's member functions can be declared inline, either by using the inline keyword or by placing the function definition within the class definition.

예제 2Example 2

// inline_keyword2.cpp
// compile with: /EHsc /c
#include <iostream>
using namespace std;

class MyClass {
public:
   void print() { cout << i << ' '; }   // Implicitly inline
private:
   int i;
};

Microsoft 전용Microsoft-specific

__inline 키워드는와 동일 inline 합니다.The __inline keyword is equivalent to inline.

를 사용 하는 경우에도 __forceinline 컴파일러는 모든 상황에서 코드를 인라인 할 수 없습니다.Even with __forceinline, the compiler can't inline code in all circumstances. 컴파일러는 다음과 같은 경우 함수를 인라인 할 수 없습니다.The compiler can't inline a function if:

  • 함수 또는 해당 호출자는 /Ob0 (디버그 빌드에 대 한 기본 옵션)를 사용 하 여 컴파일됩니다.The function or its caller is compiled with /Ob0 (the default option for debug builds).

  • 함수 및 호출자가 다양한 형식의 예외 처리(한 경우 C++ 예외 처리, 다른 경우 구조적 예외 처리)를 사용합니다.The function and the caller use different types of exception handling (C++ exception handling in one, structured exception handling in the other).

  • 함수에 가변 인수 목록이 있습니다.The function has a variable argument list.

  • 함수는, 또는로 컴파일되지 않은 경우 인라인 어셈블리를 사용 /Ox /O1 /O2 합니다.The function uses inline assembly, unless compiled with /Ox, /O1, or /O2.

  • 함수는 재귀적 이며를 설정 하지 않습니다 #pragma inline_recursion(on) .The function is recursive and doesn't have #pragma inline_recursion(on) set. pragma를 사용하면 재귀 함수가 기본 깊이 16번 호출로 인라인 처리됩니다.With the pragma, recursive functions are inlined to a default depth of 16 calls. 인라인 깊이를 줄이려면 pragma를 사용 inline_depth 합니다.To reduce the inlining depth, use inline_depth pragma.

  • 가상 함수이며 실제로 호출됩니다.The function is virtual and is called virtually. 가상 함수에 대한 직접 호출은 인라인 처리할 수 있습니다.Direct calls to virtual functions can be inlined.

  • 프로그램에서 함수의 주소를 사용하고 함수에 대한 포인터를 통해 호출합니다.The program takes the address of the function and the call is made via the pointer to the function. 주소가 사용된 함수에 대한 직접 호출은 인라인 처리할 수 있습니다.Direct calls to functions that have had their address taken can be inlined.

  • 함수는 한정자로도 표시 됩니다 naked __declspec .The function is also marked with the naked __declspec modifier.

컴파일러가로 선언 된 함수를 인라인 할 수 없는 경우 __forceinline 다음과 같은 경우를 제외 하 고 수준 1 경고가 생성 됩니다.If the compiler can't inline a function declared with __forceinline, it generates a level 1 warning, except when:

  • 함수는/Od 또는/Ob0.를 사용 하 여 컴파일됩니다.The function is compiled by using /Od or /Ob0. 이러한 경우에는 인라이닝이 필요 하지 않습니다.No inlining is expected in these cases.

  • 함수는 외부에서 포함 된 라이브러리나 다른 변환 단위에서 정의 되거나 가상 호출 대상 또는 간접 호출 대상입니다.The function is defined externally, in an included library or another translation unit, or is a virtual call target or indirect call target. 컴파일러가 현재 변환 단위에서 찾을 수 없는 인라인 되지 않은 코드를 식별할 수 없습니다.The compiler can't identify non-inlined code that it can't find in the current translation unit.

재귀 함수는 inline_depth 최대 16 개의 호출까지 pragma로 지정 된 깊이까지 인라인 코드로 바꿀 수 있습니다.Recursive functions can be replaced with inline code to a depth specified by the inline_depth pragma, up to a maximum of 16 calls. 해당 깊이 이후 재귀 함수 호출은 함수의 인스턴스 호출로 처리됩니다.After that depth, recursive function calls are treated as calls to an instance of the function. 인라인 추론에서 재귀 함수를 검사 하는 깊이는 16을 초과할 수 없습니다.The depth to which recursive functions are examined by the inline heuristic can't exceed 16. inline_recursionPragma는 현재 확장 중인 함수의 인라인 확장을 제어 합니다.The inline_recursion pragma controls the inline expansion of a function currently under expansion. 관련 정보는/Ob ( 인라인 함수 확장 ) 컴파일러 옵션을 참조 하세요.See the Inline-Function Expansion (/Ob) compiler option for related information.

Microsoft 전용 종료END Microsoft Specific

지정자 사용에 대 한 자세한 내용은 inline 다음을 참조 하세요.For more information on using the inline specifier, see:

인라인 함수 사용 시기When to use inline functions

인라인 함수는 전용 데이터 멤버에 액세스하는 것처럼 작은 함수에서 가장 적합하게 사용됩니다.Inline functions are best used for small functions such as accessing private data members. 이러한 한 줄 또는 두 줄 "접근자" 함수의 주요 목적은 개체에 대 한 상태 정보를 반환 하는 것입니다.The main purpose of these one- or two-line "accessor" functions is to return state information about objects. Short 함수는 함수 호출의 오버 헤드를 구분 합니다.Short functions are sensitive to the overhead of function calls. 더 긴 함수는를 호출 하 고 시퀀스를 반환 하는 데 걸리는 시간을 줄이고 인라인에서 더 많은 이점을 제공 합니다.Longer functions spend proportionately less time in the calling and returning sequence and benefit less from inlining.

클래스는 다음과 Point 같이 정의할 수 있습니다.A Point class can be defined as follows:

// when_to_use_inline_functions.cpp
class Point
{
public:
    // Define "accessor" functions as
    //  reference types.
    unsigned& x();
    unsigned& y();
private:
    unsigned _x;
    unsigned _y;
};

inline unsigned& Point::x()
{
    return _x;
}
inline unsigned& Point::y()
{
    return _y;
}
int main()
{
}

좌표 조작이 이러한 클래스의 클라이언트에서 상대적으로 일반적인 작업 이라고 가정 하 x 고, y 일반적으로 inline 오버 헤드를 저장 하는 두 접근자 함수 (앞의 예제에서는)를 지정 합니다.Assuming coordinate manipulation is a relatively common operation in a client of such a class, specifying the two accessor functions (x and y in the preceding example) as inline typically saves the overhead on:

  • 함수 호출(개체의 주소를 스택에 전달 및 배치하는 매개 변수 포함)Function calls (including parameter passing and placing the object's address on the stack)

  • 호출자의 스택 프레임의 보존Preservation of caller's stack frame

  • 새 스택 프레임 설정New stack frame setup

  • 반환 값 전달Return-value communication

  • 이전 스택 프레임 복원Restoring the old stack frame

  • 반환 값Return

인라인 함수와 매크로 비교Inline functions vs. macros

인라인 함수는 컴파일 시간에 호출 지점에서 함수 코드가 확장 되기 때문에 매크로와 비슷합니다.Inline functions are similar to macros, because the function code is expanded at the point of the call at compile time. 그러나 인라인 함수는 컴파일러에 의해 구문 분석 되 고 매크로는 전처리기에 의해 확장 됩니다.However, inline functions are parsed by the compiler, and macros are expanded by the preprocessor. 그 결과 몇 가지 중요한 차이가 생깁니다.As a result, there are several important differences:

  • 인라인 함수는 일반 함수에 적용되는 모든 형식 안전성 프로토콜을 따릅니다.Inline functions follow all the protocols of type safety enforced on normal functions.

  • 인라인 함수는 inline 함수 선언에 키워드를 포함 한다는 점을 제외 하 고 다른 함수와 동일한 구문을 사용 하 여 지정 됩니다.Inline functions are specified using the same syntax as any other function except that they include the inline keyword in the function declaration.

  • 인라인 함수에 인수로 전달된 식은 한 번 계산됩니다.Expressions passed as arguments to inline functions are evaluated once. 매크로에 인수로 전달된 식은 경우에 따라 여러 번 계산할 수 있습니다.In some cases, expressions passed as arguments to macros can be evaluated more than once.

다음 예제에서는 소문자를 대문자로 변환하는 매크로를 보여 줍니다.The following example shows a macro that converts lowercase letters to uppercase:

// inline_functions_macro.c
#include <stdio.h>
#include <conio.h>

#define toupper(a) ((a) >= 'a' && ((a) <= 'z') ? ((a)-('a'-'A')):(a))

int main() {
   char ch;
   printf_s("Enter a character: ");
   ch = toupper( getc(stdin) );
   printf_s( "%c", ch );
}
//  Sample Input:  xyz
// Sample Output:  Z

식의 의도는 toupper(getc(stdin)) 콘솔 장치 ()에서 문자를 읽고 stdin 필요한 경우 대문자로 변환 하는 것입니다.The intent of the expression toupper(getc(stdin)) is that a character should be read from the console device (stdin) and, if necessary, converted to uppercase.

매크로의 구현으로 인해 getc 은 한 번 실행 되어 문자가 "a" 보다 크거나 같은지 확인 하 고, "z" 보다 작거나 같은지 여부를 확인 합니다.Because of the implementation of the macro, getc is executed once to determine whether the character is greater than or equal to "a," and once to determine whether it's less than or equal to "z." 해당 범위에 속할 경우 문자를 대문자로 변환하기 위해 getc가 다시 실행됩니다.If it is in that range, getc is executed again to convert the character to uppercase. 즉, 프로그램은 한 번만 기다려야 하는 경우 두 개 또는 세 개의 문자를 대기 합니다.It means the program waits for two or three characters when, ideally, it should wait for only one.

인라인 함수는 전에 설명한 문제를 해결합니다.Inline functions remedy the problem previously described:

// inline_functions_inline.cpp
#include <stdio.h>
#include <conio.h>

inline char toupper( char a ) {
   return ((a >= 'a' && a <= 'z') ? a-('a'-'A') : a );
}

int main() {
   printf_s("Enter a character: ");
   char ch = toupper( getc(stdin) );
   printf_s( "%c", ch );
}
Sample Input: a
Sample Output: A

참고 항목See also

noinline
auto_inline