문제

언제 키워드를 작성해야합니까? inline C ++의 함수/방법에 대해?

몇 가지 답변을 본 후 몇 가지 관련 질문이 있습니다.

  • 언제 야 ~ 아니다 C ++의 함수/메소드에 대한 키워드 '인라인'을 작성 하시겠습니까?

  • 컴파일러는 언제 '인라인'기능/메소드를 만드는시기를 알지 못합니까?

  • 응용 프로그램이 있으면 중요합니까? 멀티 스레드 함수/메소드에 대해 '인라인'을 쓸 때?

도움이 되었습니까?

해결책

오, 내 애완 동물 오줌 중 하나.

inline 더 비슷합니다 static 또는 extern 컴파일러에게 기능을 인화하도록 지시하는 지침보다. extern, static, inline 컴파일러가 아닌 링커가 거의 독점적으로 사용하는 Linkage Directrives입니다.

그것은 말합니다 inline 컴파일러에 대한 힌트 기능은 기능을 상환해야한다고 생각합니다. 그것은 1998 년에 사실 이었을지 모르지만 10 년 후 컴파일러는 그러한 힌트가 필요하지 않습니다. 말할 것도없이 인간은 코드를 최적화 할 때 일반적으로 잘못되므로 대부분의 컴파일러는 '힌트'를 무시합니다.

  • static - 변수/기능 이름은 다른 번역 단위에서 사용할 수 없습니다. 링커는 실수로 다른 번역 장치의 정적으로 정의 된 변수/함수를 사용하지 않도록해야합니다.

  • extern -이 변환 단위 에서이 변수/함수 이름을 사용하지만 정의되지 않은 경우 불만을 제기하지 마십시오. 링커는이를 분류하고 외부 기호를 사용하려는 모든 코드에 주소가 있는지 확인합니다.

  • inline -이 기능은 여러 번역 단위로 정의되며 걱정하지 마십시오. 링커는 모든 번역 장치가 변수/함수의 단일 인스턴스를 사용하도록해야합니다.

메모: 일반적으로 템플릿을 선언합니다 inline 그들이 연계 의미를 가지고 있기 때문에 무의미합니다. inline 이미. 그러나 템플릿의 명시 적 전문화 및 인스턴스화 필요하다 inline 사용될.


귀하의 질문에 대한 구체적인 답변 :

  • C ++의 함수/메소드에 대한 키워드 '인라인'을 언제 작성해야합니까?

    기능이 헤더에 정의되기를 원할 때만. 함수의 정의가 여러 번역 단위로 나타날 수있는 경우에만 정확하게. 코드를 최적화하면서 컴파일러와 함께 작업 할 자세한 정보를 제공하므로 헤더 파일에서 작은 (한 라이너에서와 같이) 기능을 정의하는 것이 좋습니다. 또한 컴파일 시간을 증가시킵니다.

  • C ++의 함수/메소드에 대한 키워드 '인라인'을 언제 쓰지 않아야합니까?

    컴파일러가 상감하면 코드가 더 빨리 실행될 것이라고 생각하기 때문에 인라인을 추가하지 마십시오.

  • 컴파일러는 언제 '인라인'기능/메소드를 만드는시기를 알지 못합니까?

    일반적으로 컴파일러는 귀하보다 더 잘 수행 할 수 있습니다. 그러나 컴파일러는 기능 정의가없는 경우 코드를 인라인으로하는 옵션이 없습니다. 최대 최적화 된 코드에서 일반적으로 모두 private 방법이 당신이 그것을 요구하는지 여부에 관계없이 감소됩니다.

    GCC의 인라인을 방지하기 위해 제쳐두고 사용하십시오. __attribute__(( noinline )), 및 Visual Studio에서 사용하십시오 __declspec(noinline).

  • 기능/메소드에 대해 '인라인'을 쓸 때 응용 프로그램이 멀티 스레드 인 경우 중요합니까?

    멀티 스레딩은 어떤 식 으로든 인라인에 영향을 미치지 않습니다.

다른 팁

나는이 스레드의 모든 위대한 답변에 기여하고 남아있는 오해를 분산시킬 수있는 설득력있는 예제가 있습니다.

다음과 같은 두 가지 소스 파일이 주어졌습니다.

  • inline111.cpp :

    #include <iostream>
    
    void bar();
    
    inline int fun() {
      return 111;
    }
    
    int main() {
      std::cout << "inline111: fun() = " << fun() << ", &fun = " << (void*) &fun;
      bar();
    }
    
  • inline222.cpp :

    #include <iostream>
    
    inline int fun() {
      return 222;
    }
    
    void bar() {
      std::cout << "inline222: fun() = " << fun() << ", &fun = " << (void*) &fun;
    }
    

  • 사례 A :

    엮다:

    g++ -std=c++11 inline111.cpp inline222.cpp
    

    산출:

    inline111: fun() = 111, &fun = 0x4029a0
    inline222: fun() = 111, &fun = 0x4029a0
    

    논의:

    1. 당신은 당신의 인라인 함수에 대한 동일한 정의를 가져야한다면, C ++ 컴파일러는 그렇지 않은 경우 (실제로는 별도의 편집 확인할 방법이 없습니다). 이것을 보장하는 것은 당신의 의무입니다!

    2. 링커는 불평하지 않습니다 하나의 정의 규칙, 처럼 fun() 로 선언됩니다 inline. 그러나 왜냐하면 inline111.cpp 첫 번째 번역 장치입니다 (실제로 호출 fun()) 컴파일러에 의해 처리 된 컴파일러는 인스턴스를 인스턴스화한다 fun() 그것에 첫 번째 콜센터 inline111.cpp. 컴파일러가 결정된 경우 ~ 아니다 확장하려면 fun() 프로그램의 다른 곳에서 전화를 받으면 (예를 들어 ~에서 inline222.cpp),, 전화 fun() 항상 생산 된 인스턴스와 연결됩니다 inline111.cpp (전화 fun() 내부에 inline222.cpp 해당 번역 장치에서 인스턴스를 생성 할 수도 있지만 inkind는 계속 유지됩니다). 실제로, 그것은 동일한 것과 분명합니다 &fun = 0x4029a0 인쇄물.

    3. 마지막으로 inline 컴파일러에 대한 제안 실제로 확장 한 라이너 fun(), 그것 무시합니다 당신의 제안은 완전히, 이것은 분명합니다 fun() = 111 두 줄에.


  • 사례 B :

    엮다 (통지 역 순서):

    g++ -std=c++11 inline222.cpp inline111.cpp
    

    산출:

    inline111: fun() = 222, &fun = 0x402980
    inline222: fun() = 222, &fun = 0x402980
    

    논의:

    1. 이 사례는 논의 된 내용을 주장합니다 케이스 A.

    2. 실제 전화를 댓글을 달면 중요한 지적을 주목하십시오. fun() 안에 inline222.cpp (예를 들어 댓글을 달아라 cout-진전 inline222.cpp 완전히) 그런 다음 번역 장치의 편집 순서에도 불구하고 fun() 첫 번째 호출 만남에 인스턴스화됩니다. inline111.cpp, 인쇄물을 초래합니다 사례 b ~처럼 inline111: fun() = 111, &fun = 0x402980.


  • 사례 C :

    엮다 (통지 -O2):

    g++ -std=c++11 -O2 inline222.cpp inline111.cpp
    

    또는

    g++ -std=c++11 -O2 inline111.cpp inline222.cpp
    

    산출:

    inline111: fun() = 111, &fun = 0x402900
    inline222: fun() = 222, &fun = 0x402900
    

    논의:

    1. 그대로 여기에 설명되어 있습니다, -O2 최적화는 컴파일러를 장려합니다 실제로 확장 감소 할 수있는 기능 (또한 주목하십시오. -fno-inline ~이다 기본 최적화 옵션없이). 여기서 아웃 프린트에서 분명한 바와 같이 fun() 실제로 그랬습니다 인라인 확장 (그 정의에 따라 특정한 번역 단위), 2 개 다른 fun() 인쇄물. 그럼에도 불구하고 여전히 있습니다 단 하나 전 세계적으로 연결된 인스턴스 fun() (표준에 의해 요구되는대로) 동일한 &fun 인쇄.

템플릿 전문화를 수행 할 때 여전히 기능을 명시 적으로 인라인해야합니다 (전문화가 .h 파일에있는 경우)

1) 요즘에는 거의 없습니다. 함수를 인화하는 것이 좋은 생각이라면 컴파일러가 도움없이이를 수행합니다.

2) 항상. #1 참조.

(질문을 두 가지 질문으로 깨뜨렸다는 것을 반영하도록 편집되었습니다 ...)

C ++의 함수/메소드에 대한 키워드 '인라인'을 언제 쓰지 않아야합니까?

함수가 .cpp 파일, 당신은해야합니다 ~ 아니다 키워드를 작성하십시오.

컴파일러는 언제 '인라인'기능/메소드를 만드는시기를 알지 못합니까?

그러한 상황은 없습니다. 컴파일러는 기능을 인라인으로 만들 수 없습니다. 그것이 할 수있는 일은 함수에 대한 일부 또는 모든 호출을 인화하는 것입니다. 함수 코드가 없으면 그렇게 할 수 없습니다 (이 경우 링커는 그렇게 할 수있는 경우 링커가 수행해야합니다).

기능/메소드에 대해 '인라인'을 쓸 때 응용 프로그램이 멀티 스레드 인 경우 중요합니까?

아니요, 전혀 중요하지 않습니다.

  • 컴파일러는 언제 '인라인'기능/메소드를 만드는시기를 알지 못합니까?

이것은 사용 된 컴파일러에 따라 다릅니다. 요즘 컴파일러가 인간보다 인간을 더 잘 알고 있으며 성능 이유는 최적화 힌트보다는 연결 지시를 사용하지 않아야한다는 사실을 맹목적으로 믿지 마십시오. 나는 이데올로기 적으로 이러한 주장이 올바른 만남 현실이 다른 일이라는 데 동의하지만, 다른 일이 될 수있다.

주위에 여러 스레드를 읽은 후 호기심을 불러 일으키지 않은 코드에 대한 인라인의 영향을 시도했으며 결과는 GCC에 대한 측정 가능한 속도를 얻었으며 인텔 컴파일러의 속도가 빠지지 않았다는 것입니다.

(자세한 내용 : 외부 클래스 외부에 정의 된 중요한 기능이 거의없는 수학 시뮬레이션, GCC 4.6.3 (G ++ -O3), ICC 13.1.0 (ICPC -O3); 중요한 포인트에 인라인을 추가하면 GCC 코드에 대한+6% 속도를 초래했습니다).

따라서 GCC 4.6을 최신 컴파일러로 자격을 갖추면 CPU 집약적 인 작업을 작성하고 병목 현상이 정확히 어디에 있는지 아는 경우 인라인 지시문이 여전히 중요합니다.

실제로는 거의 없습니다. 당신이하는 일은 컴파일러가 주어진 함수를 인라인으로 만든다고 제안하는 것입니다 (예 : 모든 호출을이 기능으로 바꾸십시오. 물론 보장은 없습니다. 컴파일러는 지침을 무시할 수 있습니다.

컴파일러는 일반적으로 이와 같은 것들을 감지하는 데 도움이됩니다.

기본적으로 GCC는 최적화를 활성화하지 않고 컴파일 할 때 어떤 기능도 인라인하지 않습니다. Visual Studio - deft_code에 대해 잘 모르겠습니다

나는 /facs를 컴파일하고 어셈블리 코드를 살펴보면 Visual Studio 9 (15.00.30729.01)에 대해 이것을 확인했습니다. 컴파일러는 디버그 방법. 함수가 표시되어 있어도 __forceinline, 인라인 런타임 코드가 생성되지 않습니다.

리턴 유형 전에 처음에 넣고 싶습니다. 그러나 대부분의 컴파일러는 그것을 무시합니다. 정의 된 코드 블록이 더 작은 경우 대부분의 컴파일러는 어쨌든 인라인으로 간주합니다.

코드를 개발하고 디버깅 할 때, 떠나십시오 inline 밖으로. 디버깅을 복잡하게합니다.

그것들을 추가하는 주된 이유는 생성 된 코드를 최적화하는 데 도움이되는 것입니다. 일반적으로 이것은 속도를 위해 코드 공간을 증가시키는 것을 거래하지만 때로는 inline 코드 공간과 실행 시간을 모두 저장합니다.

알고리즘 완료 전에 성능 최적화에 대한 이러한 종류의 생각을 소비합니다. 조기 최적화.

인라인해야 할 때 :

1. 함수가 매개 변수 통과, 제어 전송, 제어 반환 등에 불과 할 때 발생하는 일의 오버 헤드를 피하려는 경우.

2. 기능은 작고 자주 호출되며 인라인을 만드는 것이 실제로 유리합니다. 80-20 규칙에 따라 프로그램 성능에 큰 영향을 미치는 기능을 인라인으로 만들려고 노력하십시오.

우리는 인라인이 등록과 유사한 컴파일러에 대한 요청 일 뿐이며 객체 코드 크기에 비용이들 것입니다.

도서관을 작성하거나 특별한 이유가 없다면 잊을 수 있습니다. inline 그리고 사용 링크 시간 최적화 대신에. 기능 정의가 컴파일 장치를 가로 질러 인라인을 고려하기 위해 헤더에 있어야한다는 요구 사항을 제거합니다. inline 허용.

(하지만 참조하십시오 링크 시간 최적화를 사용하지 않는 이유가 있습니까?)

C ++ 인라인 함수는 클래스에 일반적으로 사용되는 강력한 개념입니다. 함수가 인라인 인 경우 컴파일러는 컴파일 시간에 함수가 호출되는 각 지점에서 해당 함수의 코드 사본을 배치합니다.

인라인 함수로의 변경은 컴파일러가 모든 코드를 다시 한 번 교체해야하기 때문에 기능의 모든 클라이언트를 다시 컴파일해야 할 수 있습니다. 그렇지 않으면 이전 기능으로 계속됩니다.

함수를 인화하려면 함수 이름 앞에 키워드 인라인을 배치하고 함수가 함수에 대한 호출을하기 전에 함수를 정의하십시오. 컴파일러는 정의 된 함수가 라인 이상인 경우 인라인 예선을 무시할 수 있습니다.

클래스 정의의 함수 정의는 인라인 지정자를 사용하지 않아도 인라인 함수 정의입니다.

다음은 인라인 함수를 사용하여 최대 2 숫자를 반환하는 예입니다.

#include <iostream>

using namespace std;

inline int Max(int x, int y) { return (x > y)? x : y; }

// Main function for the program
int main() {
   cout << "Max (100,1010): " << Max(100,1010) << endl;

   return 0;
}

자세한 내용은 참조하십시오 여기.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top