본문 바로가기
C++/Unmanaged C++ 강좌 노트

[C++]인라인 함수

by 계양구놈팽이 2023. 3. 4.

Udemy에서 C++ 언 매니지드 프로그래밍을 수강하면서 배운 내용을 정리한 것입니다.

예제 코드

int GetAge(const Cat* ptr) const
{
	return ptr->mAge;
}

void Foo()
{
	Cat myCat(2,"츄츄");
    int myCatAge = myCat.GetAge();
}

int main()
{
	Foo();
    return 0;
}

앞서 설명되었 다시 피 함수는 호출되면서 스택의 공간을 할당받아 사용한다. 

  1. main이 에서 Foo() 함수가 호출된다.
    1. myCat 개체를 위한 공간을 할당받는다.
    2. myCatAge 변수를 위한 공간을 할당받는다.
  2. myCatAge는 값을 받기 위해 myCat개체의 GetAge함수를 호출하면서 또 스택에 새로운 공간을 할당받는다.
  3. 그러면 이제 스택은 이렇게 쌓여 있다고 보면 된다. (GetAge() 함수 - Foo() 함수 - main() 함수) GetAge()가 가장 먼저 반환된다. 그리고 순서대로 Foo함수.

스택의 빈번한 이동이 발생하였다.

함수를 호출할 때 내부에서 일어나는 일

  • 함수는 메모리 안에 "할당"되어 있음
  • 함수를 호출하기 위해 필요한 단계들
  1. 변수들을 스택에 푸시
  2. 함수 주소로 점프
  3. 함수를 실행
  4. 호출자 함수로 다시 점프
  5. 1번 단에서 넣어뒀던 변수들을 Pop

반복 적인 스택의 점프

  • 그래서 좀 더 느림
  • CPU 캐시에 최적이 아님
  • 모던 CPU 아키텍처에서는 더 느림

 

  • 자잘하게 기능 별로 함수를 만드는 습관이 몸에 배였다. 가독성을 위해서도 그렇게 하라 배우기도 하였다.
  • 그렇지만, 스택에서 일어나고 있는 일을 알게 된 이상 방치할 수 없다. 함수 호출에 필요한 오버 헤드를 최적화할 수 없을까?

인라인(inline) 함수

인라인 함수의 동작 원리는 복붙이랑 비슷하다.

  • 함수 호출 대신에 함수의 내용을 호출자 함수로 붙여 넣기 해주는 것이다. 누가? 컴파일러!!
void Foo()
{
	Cat myCat(2,"츄츄");
    int myCatAge = myCat.mAge;
}
  • 사전 처리기로 define 해서 간단한 기능을 메크로 처리하는 것과 유사해 보이지만, 실제는 그렇지 않다.
  • 인라인 함수는 컴파일하는 도중에 액세스 처리를 하고, 컴파일러가 inline선언된 함수를 코드에 붙여주는 것이다.

인라인 함수 주의점

  • inline 키워드는 가이드일 뿐이다.
    • 실제로는 인라인 되지 않을 수 있다.(강력하게 피력할 뿐)
    • 컴파일러가 inline을 처리하는 게 최적화하는데 적합하지 않다고 생각하면 하지 않는다. 반대로 inline선언을 안 했지만, 컴파일러가 자가판단으로 최적화를 위해서 inline처리를 할 수 있다.
  • 간단한 함수에 적합
    • getter 혹은 setter 같은거
    • 간단한 수식을 포함한 함수