KoreanFoodie's Study

Effective C++ | 항목 30 : 인라인 함수는 미주알고주알 따져서 이해해 두자 본문

Tutorials/C++ : Advanced

Effective C++ | 항목 30 : 인라인 함수는 미주알고주알 따져서 이해해 두자

GoldGiver 2022. 10. 25. 16:26

C++ 프로그래머의 필독서이자 바이블인, 스콧 마이어스의 Modern Effective C++ 를 읽고 기억할 내용을 요약하고 있습니다. 꼭 읽어보시길 추천드립니다!

항목 30 : 인라인 함수는 미주알고주알 따져서 이해해 두자

핵심 :

1. 함수 인라인은 작고, 자주 호출되는 함수에 대해서만 하자. 이렇게 하면 디버깅 및 라이브러리의 바이너리 업그레이드가 용이해지고, 자칫 생길 수 있는 코드 부풀림 현상이 최소화되며, 프로그램의 속력이 더 빨라질 수 있는 여지가 최고로 많아진다.
2. 함수 템플릿이 대개 헤더 파일에 들어간다는 일반적인 부분만 생각해서 이들을 inline 으로 선언하면 안 된다.


인라인 함수를 사용하면 컴파일러가 함수 본문에 대해 문맥별(context-specific) 최적화를 걸기가 용이해진다. 목적 코드의 크기도 작아지며 명령어 캐시 적중률도 높아진다.
inline 은 컴파일러에 대해 '요청'을 하는 것이지, '명령' 이 아니다. 즉, inline 을 붙이지 않아도 그냥 되는 경우도 있고 명시적으로 할 수도 있다는 뜻이다. 암시적인 inline 의 예시를 보자.

class Person
{
  public:
    ...
    // age 는 클래스 정의 내부에서 정의됨
    int age() const { return theAge; }
  private:
    int theAge;
};

대부분의 경우, inline 함수는 컴파일 도중에 수행하므로 헤더 파일에 넣어주는 것이 좋다. 하지만 복잡한 함수나 가상함수는 인라인해 주지 않는다. 다음 예시들을 보면서, 인라인이 될 수 있는 경우와 아닌 경우를 살펴보자.

// f 의 호출은 컴파일러가 인라인해 준다고 가정
inline void f() { ... }

// pf 는 f 를 가리키는 함수 포인터
void (*pf)() = f;
...
// 이 함수는 인라인화 될 것임
f();

// 이 함수는 인라인화되지 않음
// 함수 포인터를 통해 호출되고 있으므로!
pf();


생성자와 소멸자도 인라인화하기에 그리 좋지 않은 함수이다. 다음의 예를 보자.

class Base
{
private:
  std::string bm1, bm2;
};

class Derived: public Base
{
public:
  // Derived 생성자가 비어 있다
  // 정말 비어 있을까?
  Derived() {}
private:
  std::string dm1, dm2, dm3;
};

위의 Derived 생성자는 비어 있는 것처럼 보이지만, 실제로는 아래와 같이 동작할 것이다(실제 코드가 저렇게 생성된다는 뜻은 아니다).

class Derived: public Base
{
public:
  // Derived 생성자가 비어 있다
  // 정말 비어 있을까?
  Derived() 
  {
    Base::Base();

    // dm1 생성을 시도
    try { dm1.std::string::string(); }
    // dm1 생성 도중 예외를 던지면?
    // 기본 클래스 부분 소멸 후 예외 전파
    catch (...)
    {
      Base::~Base();
      throw;
    }
    // dm2, dm3 에 대해서도 위와 동일
  }
private:
  std::string dm1, dm2, dm3;
};


그렇다면 어떤 함수를 인라인으로 선언해야 하고 어떤 것을 선언하지 말아야 할까?
우선, 아무것도 인라인하지 말자. 아니면 정말 단순한 함수만 인라인화를 하자. 만약 f 라는 특정 함수가 인라인화 되어 있고, 해당 함수를 이용한 응용 프로그램을 만들었다고 가정하자. 만약 나중에 이 함수를 바꾸면, 이 함수를 이용한 모든 프로그램을 다시 컴파일 해야 한다. 하지만 인라인이 아니라면, 링크만 해주면 되므로 비용이 훨씬 덜 들게 될 것이다!

Comments