>  기사  >  백엔드 개발  >  C++ 함수 인라인

C++ 함수 인라인

黄舟
黄舟원래의
2017-02-06 13:38:521095검색

1. 매크로 코드를 인라인으로 대체


C++ 언어는 함수의 실행 효율성(속도)을 향상시키는 것이 목적인 함수 인라인을 지원합니다.

C 프로그램에서는 매크로 코드를 사용하여 실행 효율성을 높일 수 있습니다. 매크로 코드 자체는 함수가 아니지만 함수처럼 작동합니다. 전처리기는 매크로 코드를 복사하여 함수 호출을 대체하므로 매개변수를 스택에 푸시하고, 어셈블리 언어 CALL 호출을 생성하고, 매개변수를 반환하고, 반환을 실행하는 등의 작업을 수행할 필요가 없으므로 속도가 향상됩니다. 매크로 코드 사용의 가장 큰 단점은 오류가 발생하기 쉽다는 것입니다. 전처리기는 매크로 코드를 복사할 때 예상치 못한 부작용을 일으키는 경우가 많습니다.


예를 들어

#define MAX(a, b)         (a) > (b) ? (a) : (b)

result = MAX(i, j) + 2 ;

는 전처리기에 의해

result = (i) > (j) ? (i) : (j) + 2 ;

로 해석됩니다. ' + '보다 연산자' :'가 우선순위가 높으므로 위의 문은 예상되는

result = ( (i) > (j) ? (i) : (j) ) + 2 ;

와 동일하지 않습니다. 매크로 코드를

#define MAX(a, b) ( (a) > (b) ? (a) : (b) )

로 다시 작성하면 문제를 해결할 수 있습니다. 우선순위 실수로 인한 문제. 그러나 수정된 ​​매크로 코드를 사용해도 완벽하지는 않습니다. 예를 들어

result = MAX(i++, j);

문은 전처리기에 의해

result = (i++) > (j) ? (i++) : (j);

로 해석됩니다. C++의 경우 매크로 코드 사용에는 또 다른 단점이 있습니다. 클래스의 멤버는 조작할 수 없습니다. 이는 매크로 코드가 기본적으로 공개 또는 전역 조작을 위한 것임을 의미합니다.


C++에서 "함수 인라인"이 어떻게 작동하는지 살펴보겠습니다. 인라인 함수의 경우 컴파일러는 함수 선언(이름, 매개변수 유형, 반환 값 유형 포함)을 기호 테이블에 배치합니다. 컴파일러가 인라인 함수에서 오류를 발견하지 못한 경우 해당 함수에 대한 코드도 기호 테이블에 배치됩니다. 인라인 함수를 호출할 때 컴파일러는 먼저 호출이 올바른지 확인합니다(유형 안전성 검사를 수행하거나 자동 유형 변환을 수행합니다. 물론 모든 함수에 대해 동일함). 정확하다면 인라인 함수에 대한 코드가 함수 호출을 직접 대체하므로 함수 호출의 오버헤드가 제거됩니다. 이 프로세스는 전처리기가 유형 안전성 검사를 수행하거나 자동 유형 변환을 수행할 수 없기 때문에 전처리와 크게 다릅니다. 인라인 함수가 멤버 함수인 경우 객체의 주소(this)가 적절한 위치에 배치되는데 이는 전처리기가 할 수 없는 작업입니다.


C++ 언어의 함수 인라인 메커니즘은 매크로 코드의 효율성을 가질 뿐만 아니라 보안을 강화하고 클래스의 데이터 멤버를 자유롭게 조작할 수 있습니다. 따라서 C++ 프로그램에서는 모든 매크로 코드를 인라인 함수로 바꿔야 합니다. 아마도 유일한 예외는 "assert"일 것입니다. Assert는 디버그 버전에서만 작동하는 매크로입니다. 발생해서는 안 되는 상황을 확인하는 데 사용됩니다. 프로그램의 디버그 버전과 릴리스 버전 사이에 차이가 발생하지 않도록 하려면 어설션에 부작용이 없어야 합니다. Assert가 함수인 경우 함수 호출로 인해 메모리와 코드가 변경되므로 디버그 버전과 릴리스 버전 간에 차이가 있습니다. 따라서 Assert는 함수가 아니라 매크로입니다.


2. 인라인 함수의 프로그래밍 스타일


인라인 키워드는 함수 정의 본문과 함께 배치되어야 합니다. 함수를 인라인으로 만들려면 함수 선언 앞에 inline을 넣는 것만으로는 효과가 없습니다. 다음 스타일의 Foo 함수는 인라인 함수가 될 수 없습니다:

inline void Foo(int x, int y);   // inline 仅与函数声明放在一起,不起任何作用  
void Foo(int x, int y)  
{  
…  
}

. 그러나 다음 스타일의 Foo 함수는 인라인 함수가 됩니다:

void Foo(int x, int y);    
inline void Foo(int x, int y) // inline 与函数定义体放在一起  
{  
…  
}


그래서 인라인 "선언용 키워드"라기 보다는 "구현용 키워드" 입니다. 일반적으로 사용자는 함수 선언을 읽을 수 있지만 함수 정의는 볼 수 없습니다. 대부분의 교과서에서는 인라인 함수의 선언과 정의 본문 앞에 inline 키워드를 추가하지만, 함수 선언에 inline이 나오면 안 된다고 생각합니다. 이 세부 사항은 함수의 기능에 영향을 미치지 않지만 고품질 C++/C 프로그래밍 스타일의 기본 원칙을 반영합니다. 선언과 정의는 혼동될 수 없으며 사용자는 함수에 필요한지 여부를 알 필요도 없고 알아서도 안 됩니다. 인라인됩니다.


클래스 선언에 정의된 멤버 함수는 자동으로 인라인 함수가 됩니다. 예를 들어

class A  
{  
public:  
    void Foo(int x, int y) { … }   // 自动地成为内联函数  
}


는 클래스 선언에 있는 멤버 함수의 정의 본문은 작성의 편의성을 제공하므로 좋은 프로그래밍 스타일이 아닙니다.

// 头文件  
class A  
{  
public:  
    void Foo(int x, int y);  
}  
// 定义文件  
inline void A::Foo(int x, int y)  
{  
…  
}

3. 인라인을 주의해서 사용하세요.


인라인 처리를 하면 함수의 실행 효율성을 높일 수 있습니다. 모든 함수를 인라인 함수로 정의하면 어떨까요?


모든 함수가 인라인 함수인 경우에도 "inline" 키워드가 필요한가요?


인라이닝은 코드 확장(중복)을 희생하고 함수 호출의 오버헤드만 절약하므로 함수 실행 효율성이 향상됩니다. 함수 본문의 코드를 실행하는 시간이 함수 호출의 오버헤드보다 길면 효율성 향상이 매우 작습니다. 반면, 각 인라인 함수 호출에는 코드 중복이 필요하므로 프로그램의 전체 코드 크기가 늘어나고 더 많은 메모리 공간을 사용하게 됩니다. 다음과 같은 상황에서는 인라인 처리를 사용하는 것이 적절하지 않습니다.


(1) 함수 본문의 코드가 상대적으로 긴 경우 인라인 처리를 사용하면 메모리 소모 비용이 높아집니다. .


(2) 함수 몸체에서 루프가 발생하면 함수 몸체의 코드를 실행하는 데 걸리는 시간이 함수 호출 비용보다 길어집니다.


인라인을 사용하는 것이 더 효율적이기 때문에 클래스의 생성자와 소멸자를 오해하기 쉽습니다. 생성자와 소멸자를 주의하세요. 함수는 기본 클래스나 멤버 개체의 생성자와 소멸자를 "은밀하게" 실행하는 등의 일부 동작을 숨길 수 있습니다. 따라서 클래스 선언에 생성자와 소멸자의 정의를 아무렇게나 넣지 마십시오.

위는 C++ 함수 인라인 내용입니다. 더 많은 관련 내용은 PHP 중국어 홈페이지(www.php.cn)를 참고해주세요!


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.