2011-08-26 3 views
2

여러분,C++ - 함수 인라이닝을 사용할 수없는 경우?

내가 읽고 있었다 "Thinking in C++". -이 문을 발생하는 경우, (장 인라인 함수)를

는"컴파일러는 인라인을 수행 할 수있는 함수의 주소가 암시 적으로 가지고가는 경우에 또는 명시 적으로 taking address of function implicitly or explicitly? "는이 경우 인라인 할 수 없습니다 왜
을".

은 그 무엇을 의미합니까? "

감사합니다.

+3

, 그 주소는? – Stan

답변

4

실제로 견적은 오도 할 수 있습니다.

함수 주소를 취하면 라이브러리/실행 파일에 함수를 생성해야합니다. 주소로 함수를 실행하면 명령 포인터를 함수를 설명하는 코드 블록으로 건너 뛸 수 있기 때문입니다.

그러나 직접 호출 한 경우 컴파일러가 다른 위치에서 함수를 인라인하는 것을 확실히 방지하지는 못합니다.

첫째, 리뷰 :

// Explicit: 
void foo(); 

void (*func_ptr)() = foo; 


// Implicit 
struct Foo { virtual void bar() {} }; // address used in V-Table 

둘째, 인라인 예 : 함수가 '인라인'경우

int main() { 
    (*func_ptr)(); // probably not inlined as the compiler can difficultly assert 
       // that nobody may modified it... since it's non-const. 

    foo(); // might be inlined 

    Foo f; 
    f.bar(); // might be inlined (the exact type of `f` is known) 
      // this is called, "devirtualizing" 

    Foo& g = accessSomeFoo(); 
    g.bar(); // probably not inlined unless the compiler can assert 
      // the type returned by accessSomeFoo 
      // (which requires knowing its definition) 
} 
5

기능 주소는 assigning it to a function pointer을 의미합니다. 이것은 링크 된 예제 에서처럼 명시 적으로 발생할 수 있습니다. 저자가 "암시 적으로"무엇을 의미하는지 잘 모르겠습니다. 아마도 다른 함수에 매개 변수로 함수를 전달하는 것과 같습니다.

함수의 주소를 사용하는 경우 먼저 주소가 있어야합니다. 인라이닝은 기본적으로 함수의 호출을 본문의 복사본으로 대체하는 것을 의미하므로 그러한 변환 후에 함수가 더 이상 존재하지 않으므로 주소가 없습니다 - n 동일한 코드의 복사본이 있었지만 기능. 따라서 함수의 주소가 어떤 식 으로든 사용되면 인라인 될 수 없습니다.

+2

글쎄, 이론적으로 그것은 될 수 있습니다. 'void foo (void);와 같은 코드; void (* p) (void) = &foo; p();'* 컴파일러에 의해 최적화 될 수있다. –

+0

+1 .......... 짧고 달콤한 답변 : –

+0

속도가 최적화 된 컴파일러가 함수 포인터로 아무 것도하지 않는 모든 부분을 인라인 할 것입니까? – TravisG

1

전적으로 사실인지 잘 모르겠습니다. 그러나 함수의 주소를 사용하는 경우 해당 함수는 함수의 전처리 및 정리 코드가있는 메모리에 있어야합니다. 인라인 할 때 생략되는 것은이 전제 및 정리입니다. 또한 인라인 될 때 ​​최적화 가능성을 완전히 누릴 수 있습니다.

그러나 현대 컴파일러는 인라인 할 수있는 곳이면 어디에서나 함수를 인라인 할 수 있어야합니다. 고려 :

int compare (int a, int b) 
{ 
    return a compared to b 
} 

int main() 
{ 
    a = array of ints 

    qsort (a, compare); // take address of compare function, thus compare function exists in 
         // app as a proper function 

    compare (value1, value2); // there's no reason why this can't be inlined 
} 

내가 견적 인라인 될 수없는 사항에 대한 자세한 명시해야한다고 생각 :

는 함수 포인터를 통해 호출되는 함수가

를 인라인 할 수 없습니다.

간접 호출 (함수 포인터를 통해 호출)의 시점에서 인라인 어떤 기능이 컴파일시에 확인할 방법이 없기 때문이다. 이것은 함수 포인터가 가리키는 함수가 직접 호출되는 곳에서는 인라인 될 수 없다는 것을 의미하지는 않습니다.

+0

답안의 마지막 부분은 반드시 사실 일 필요는 없습니다. @ Peter의 답변에 대한 내 의견을 참조하십시오. –

+0

@Oli : 컴파일러에서 추론 할 수있는 함수 포인터가 확실히 인라인 될 수 있다고 생각하지만, 왜 함수 포인터를 작성하고 함수를 할당해야하는지에 대해서는 생각할 수 없습니다. 함수를 직접 호출하는 것이 아니라 간접 호출을 수행하는 것입니다. 아마도 템플릿을 사용하는 경우. – Skizz

+0

예, 템플릿이 좋은 예입니다. –

관련 문제