인라인 함수

함수를 호출할 때 일어나는 일

함수를 호출하기 위해 필요한 단계들

-> 함수 호출에는 비용이 들어간다!

  1. 변수들을 스택에 PUSH

  2. 함수 주소로 점프(스택 포인터를 옮긴다)

  3. 함수를 실행한다.

  4. 함수를 실행 후 함수를 호출 했던 함수로 다시 점프한다.

  5. 1단계에서 넣어두었던 변수들을 POP 해서 사용한다.

함수 호출에 여러 단계가 있으므로 생기는 단점

  • 단계가 많아서 조금 더 느림 ..

  • CPU 캐시에 최적이 아닐 수도 있다. -> 한번 호출한 내용에 대해서 보통은 캐시 메모리에 저장되게 되는데, 힙 메모리와 같이 전혀 다른 곳을 호출하게 되면 캐시 최적화에 문제가 될 수 있다.

  • 모던 CPU 아키텍처에서는 더 느림 ..

인라인 함수 (함수 호출의 오버헤드를 개선하는 방법)

  • 코드를 살펴보자

    • 다음과 같이 inline 키워드를 헤더 부분에 선언해주고 함수를 사용하게 되면,

    • 개발자가 보기에는 함수를 호출하는 것으로 보여지지만, 컴파일러가 함수의 코드로 바꾸어준다.

    • #define 과 같이 매크로의 개념과 매우 비슷하다. #define SQUARE(x) (x)*(x)

매크로와 비슷한데 그렇다면 대신 매크로를 사용해도 되나? -> 쓰지마 ;;

  • 하지만, 매크로는 디버깅이 너무 힘들다 ..

    • 디버깅은 컴파일 이후에 이루어진다.

  • 매크로는 안정성이 떨어진다..

    • 컴파일러가 아닌, 전처리기에 의해 동작하기 때문에 엑세스 체크, 범위를 준수하지 않는다.

  • 정말 매크로를 쓸 이유가 있지 않는 한 인라인 함수를 쓰자!

인라인 함수와 매크로는 어떤 차이점이 있을까?

매크로

  • 매크로는 전처리기에 의해서 동작한다.

  • 컴파일 타임 이전에 동작하기 때문에 엑세스 체크, 범위를 준수하지 않는다.

  • 디버깅은 컴파일 이후에 이루어지기 때문에, 매크로를 디버깅 하기 어렵다는 단점이 있다.

인라인 함수

  • 인라인 함수는 컴파일러에 의해서 동작한다.

  • 인라인 함수는 함수 호출이 아닌 해당 함수의 코드(리턴값)가 호출 지점에 직접 삽입되어 실행된다.

  • 인라인 함수는 컴파일 타임에 이루어지기 때문에, 타입 안정성을 보장하고, 디버깅 할 수 있다는 장점이 있다.

인라인 함수를 쓸 때 주의 점

inline 키워드는 힌트일 뿐이다.

  • 실제로 인라인이 안될수도 있다!?

  • 컴파일러가 자기 맘대로 인라인을 할수도 안할수도 있다.

인라인 함수 구현이 헤더 파일에 위치해야 한다!

  • 컴파일러가 .cpp 파일을 각각 따로 컴파일 한다.

  • 따라서 b.h 를 include 하는 a.cpp 파일을 컴파일 할 때, 컴파일러는 b.cpp 에 뭐가 들어있는 줄 모른다!

  • 때문에, 복붙을 하려면 컴파일러가 그 구현체를 볼 수 있어야 하기 때문에, 인라인 함수 구현이 헤더 파일에 위치해야 한다.

헤더 파일에 구현체가 있다는 것은 무엇을 의미할까?

  • 구현체의 크기가 커진다면, 해당 헤더 파일을 사용하는 모든 cpp 파일의 키기가 커진다는 것을 의미하고,

  • 헤더 파일에 구현체의 변경이 있을 경우, 풀빌드가 일어날 수 있다는 것을 의미한다. -> 헤더 파일의 영향력이 클수록 빌드 시간이 길어진다.

  • 실행파일의 크기가 커진다는 것과, 풀빌드가 일어날 수 있다는 점은 인지하고 있어야 한다.

간단한 함수에 적합하다.

  • 특히 getter, setter

실행 파일의 크기가 증가되기 쉽다.

  • 동일한 코드를 여러번 복붙하기 때문에, 실행파일의 크기가 증가하고

  • 남용하지 말자!

  • 실행 파일이 작을수록 CPU 캐시하고 잘 작동한다. -> 속도가 더 빨라질 수 있다.

Last updated