방프리

17.12.05. Effective C++ 5. 구현 (항목30) 본문

C++/Effective C++

17.12.05. Effective C++ 5. 구현 (항목30)

방프리 2020. 1. 15. 21:31

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

 

- inline 함수... 정말 좋은 키워드입니다. 원래라면 함수를 호출할 때 메모리에 함수의 이름을 저장 한 후 

함수를 호출 시 메모리에 기록된 함수의 포인터를 보고 함수를 실행시키는데요.

인라인 함수는 그 과정을 다 무시하고 함수의 내용 자체를 메모리에 올리도록 해줍니다. 

그 덕분에 실행속도도 일반 함수에 비해 굉장히 빨라지게 됩니다. 최적화에 정말 도움이 많이 되는 키워드죠

하지만 이런 좋은 inline 함수도 나름의 단점을 가지고 있습니다. 

1) 최적화에 오히려 방해가 될 수 있습니다.

- inline 함수는 함수의 내용을 통째로 컴파일러에 요청을 하는 것입니다.

즉, 내용이 많으면 많을 수록 처리량 또한 많아진다는 뜻이죠.

2) 라이브러리 파일 등을 만들 때 가장 문제점이 생깁니다.

- 컴파일러는 프로그램을 실행할 때 그 함수가 어떤 것인지 알아야 합니다. 특히 라이브러리 파일이나

링크 파일에 관련해서는 가장 중요하죠. 하지만 앞에서 말했듯이 inline 함수는 내용 자체를 등록하기 때문에

호출을 명시적으로 하지 않을 뿐더러 디버깅시 굉장히 난해하고 복잡하게 됩니다.

심지어 그 라이브러리 파일 안에 있는 inline 함수를 사용한 개발자들도 그 함수를 사용한 코드를 다 수정해야 하는

불상사까지 벌여질 수도 있습니다. 

3) 가상함수는 inline 함수가 안됩니다.

- 당연하지만 가상함수는 어떤 함수를 사용할 지 런타임에 결정하겠다는 것이고, inline은 함수를 어떤 위치에 끼워

넣을지 고려를 컴파일 타임 때 하겠다는 뜻이므로 가상함수를 inline을 돌리는건 말이 안됩니다.

4) 생성자 & 소멸자는 inlining을 하기엔 적절치 못한 장소입니다.

- 생성자, 소멸자... 아무것도 없다고 무작정 inlining을 하시는 분은 없을 거라 생각합니다...

기본 디볼트로 생성되는 생성자와 소멸자엔 함수 본문 내용은 아무 것도 없지만 실제론 다릅니다. 

메모리를 할당하는 작업부터 시작해서 여러 예외처리를 하는 공간이기 때문이죠. 즉, 무엇을 해야하는지

알려주지만 그 안에서 어떻게 동작하는지는 비밀로 되어있는 함수들입니다...

어떻게 동작하는지도 규모도 얼마나 되는지 모르는데 inlining은 그야말로 도박이라고 할 수 있죠

-> 그러면 해결책은 없냐?!!!!

inline 함수는 되도록이면 사용하지 않는 것이 좋습니다. 현재 컴파일러에서는 자동으로 컴파일러가

inline에 최적화된 함수들을 자동으로 등록하고 있고, inline을 쓰더라도 내용이 벅차다면 알아서

버려버립니다. 일전에 C++ 관련 발표내용을 참고하자면 10줄 이내 코딩의 경우엔 inline을 사용하는 것이

좋다고 했던 자료를 본 적이 있습니다. 라이브러리 파일을 만드시는 개발자분이라면

굉장히 고려를 많이 하여 사용해야할 키워드일 것 같습니다.

 

이것만은 잊지말자 

* 함수 인라인은 작고, 자주 호출되는 함수에 대해서만 하는 것으로 묶어둡시다. 이렇게 하면

디버깅 및 라이브러리의 바이너리 업그레이드가 용이해지고, 자칫 생길 수 있는 코드 부풀림 현상이

최소화 되며, 프로그램의 속력이 더 빨라질 수 있는 여지가 최고로 많아집니다.

* 함수 템플릿이 대개 헤더 파일에 들어간다는 일반적인 부분만 생각해서 이들을 inline으로 선언하면 안됩니다.

Comments