본문 바로가기
C++ 200제/코딩 IT 정보

Inline함수 문제, C++ 인라인이 실패하면?

by vicddory 2017. 9. 14.

Inline함수 문제, C++ 인라인이 실패하면?


Inline함수가 인라인화될 수 없을 때 무슨 일이 발생하는가?


이론적으로, 컴파일러가 함수를 Inline함수를 거부할 때 그 함수는 보통의 함수처럼 다루어진다. 컴파일러는 그것을 위한 객체 코드를 생성하며 함수의 invocations는 그것의 메모리 주소로의 점프로 변환된다.


불행하게도 함수를 outline 화하는 것의 결과들은 그것보다 더 복잡해진다. 클래스 선언에서 Inline함수를 정의하는 것은 흔한 일이다. 예를 들면,


1
2
3
4
5
6
7
8
9
10
11
12
// filename Time.h
#include<ctime>
#include<iostream>
 
using namespace std;
 
class Time
{
public:
        inline void Show() { for (int i = 0; i<10; i++cout<<time(0)<<endl;}
};
// filename Time.h
cs

멤버 함수 Time::Show()가 하나의 지역변수와 하나의 for 루프를 포함하기 때문에 컴파일러는 inline 요청을 무시하고 그것을 보통의 멤버 함수로 다룰 것 같다.


그러나 클래스 선언 그 자체는 독립적으로 컴파일된 번역단위들 속에 #include 될 수 있다:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// filename f1.cpp
#include "Time.hj"
void f1()
{
        Time t1;
        t1.Show();
}
// f1.cpp
 
// filename f2.cpp
#include "Time.h"
void f2()
{
        Time t2;
        t2.Show();
}
// f2.cpp
cs


결과적으로 컴파일러는 같은 프로그램을 위하여 같은 멤버 함수의 두 개의 동일한 사본들을 생성한다:


1
2
3
4
5
6
7
8
9
10
void f1();
void f2();
 
int main()
{
    f1(); 
    f2();
 
    return 0;
}
cs


프로그램이 링크될 때 링커는 Time::Show()의 두 개의 같은 사본들과 마주친다. 보통 함수 재정의는 링크-시간 에러의 원인이 된다. 그러나 Inline함수화되지 않은 함수들은 특수한 경우이다.


객체지향프로그래밍 C++[Inline함수 문제, C++ 인라인이 실패하면?]


C++의 더 오래된 구현들은 마치 그것이 static으로 선언되었던 것처럼 Inline함수화되지 않은 함수를 다룸으로써 이 상황을 타개한다. 결론적으로 컴파일된 함수의 각 사본은 그것의 선언되었던 번역단위 내에서만 볼 수 있었다.


이것은 같은 함수의 다중의 지역 사본들의 비용에서 이름충돌(name clashing) 문제를 해결하였다. 이러면 inline 함수로 선언은 성능을 증대시키지 않는다. 이와는 대조적으로 Inline함수화되지 않은 함수의 모든 호출은 일상적인 오버헤드를 가지는 보통 함수 호출로서 해결되었다. 더 나쁜 것은 함수 코드의 다중 사본들이 컴파일 및 링크 시간을 증가시키고 실행파일의 크기를 부풀린다는 것이다.


아이러니하게도 Time::Show() inline을 선언하지 않는 것이 더 좋은 성능을 결과할 수 있다는 것이다!


C++ Inline 함수[Inline함수 문제, C++ 인라인이 실패하면?]


프로그래머는 일반적으로 이것의 실제 비용들 전부를 의식하지 않는다는 것을 기억하라.


컴파일러는 은밀히 혹사당하고 링커는 조용히 한탄하며 결과하는 실행파일은 전보다 더 부풀고 동작이 느려진다. 그러나 그것은 여전히 동작하며 그래서 사용자들은 그들의 머리를 긁적이며 말한다.


"이 객체지향 프로그래밍은 정말로 불쾌해! 이 애플리케이션은 내가 C로 작성했다면 훨씬 더 빠르게 동작할 거라고 확신해!"


다행하게도 인라인화 되지 않는 함수들에 관련된 표준의 명세는 최근에 변경되었다.


표준과 호환되는 구현은 그것을 정의하는 번역단위들의 수와 무관하게 그러한 함수의 오직 하나의 사본만을 생성한다. 다른 말로 하자면 인라인화 되지 않은 함수는 보통의 함수와 비슷하게 다룬다. 그러나 모든 컴파일러 벤더들이 새로운 명세들을 채택하려면 다소의 시간이 걸릴 것이다.


Inline함수 문제, C++ 인라인이 실패하면?

댓글