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

Jangmanbo·2024년 4월 17일
0

Effective C++

목록 보기
30/33

인라인 함수

장점

  • 함수처럼 동작하면서, 매크로보다 안전하다.
  • 함수 호출 시 발생하는 오버헤드가 없다.

주의할 점

  • 함수 본문의 길이가 길다면 목적 코드의 크기가 커지며 명령어 캐시 적중률이 떨어진다.
  • 반대로 함수 본문의 길이가 함수 호출문보다 짧다면 목적 코드의 크기가 작아지고 명령어 캐시 적중률이 높아진다.

인라인 요청 방법

암시적인 방법

class Person
{
public:
	...
	int age() const { return theAge;}	// 암시적 인라인 요청
    ...
private:
	int theAge;
};

명시적인 방법

template<typename T>
inline const T& max(const T& a, const T& b) { return a < b ? b : a; }	// 명시적 인라인 요청

그러나 대부분의 컴파일러는 인라인 함수로 선언되어있어도 복잡한 함수(ex. 재귀, 루프, ...)와 가상 함수는 인라인하지 않는다.

즉, 실제로 인라인이 되는지는 컴파일러가 결정한다.


인라인 조건을 갖추었지만 함수 본문을 만드는 경우

inline void f() { ... }				// 인라인 함수
void (*pf) () = f;					// f를 가리키는 함수 포인터
...
f();								// 인라인
pf();								// 아웃라인

인라인 함수의 주소를 취하는 코드가 있으면, 컴파일러는 이 코드를 위해 아웃라인 함수 본문을 만들어야만 한다.
따라서 확실한 인라인 함수도 어떻게 호출하느냐에 따라 인라인되기도, 안되기도 한다.

생성자, 소멸자는 인라인하지 말자!

생성자, 소멸자는 런타임에 아웃라인 본문을 만들어버릴 수 있다.
이렇게 런타임에 본문이 바뀔 수 있으므로 인라인하기 적합하지 않다.

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

class Derived: public Base
{
public:
    Derived() {}
private:
    std::string dm1, dm2, dm3;
};

여기서 Derived의 생성자는 인라인하기 좋아 보이지만 실상은 그렇지 않다.

C++은 객체가 생성될 때 객체의 데이터 멤버들도 생성하고, 객체가 소멸될 때 객체의 데이터 멤버들을 소멸한다.
따라서 함수 본문이 비어있어보여도, 실제로는 데이터 멤버를 생성/삭제하는 코드들이 포함될 수 있다.



결론

  • 작고, 자주 호출되는 함수만 인라인하자.

0개의 댓글