개발하는 리프터 꽃게맨입니다.

[C++] 인라인 함수 본문

언어/C, C++

[C++] 인라인 함수

파워꽃게맨 2024. 1. 8. 13:11

함수 호출의 단계

함수를 정의하고 컴파일하면, 함수는 기본적으로 메모리의 '코드 섹션'에 저장되고

알맞은 고유의 주소를 가집니다.

 

그리고 함수 호출 시에는 스택에 함수의 주소를 올려

함수의 본체(body)를 찾아 실행하는 단계를 거치게 되죠.

 

함수 정의와 함수 호출에는 생각보다 오버헤드가 조금 있습니다.

 

1) 함수를 사용하기 위해 기존 레지스터에 들어있던 값을 스택에 푸시

2) 현재 PC(Program Counter) 값을 스택에 푸시

3) 함수 주소로 PC값을 변경하여 점프

4) 함수 실행

5) 기존 PC값과 레지스터 값을 스택에서 팝 하여 복구

 

이런 단계 때문에 함수 호출은 기본적으로 코드를 쌩으로 사용하는 것보다는

속도가 느리다는 단점이 있습니다.

그래서 '재귀'라는 알고리즘 메커니즘이 속도가 느리죠.

 

물론, 반복적인 코드를 사용할 시 함수를 사용하면

가독성과 유지 보수성이 좋다 진다는 장점이 있지만

 

한 줄, 두줄 짜리 코드를 함수에 넣기는 부담스러울 수 있습니다.

그런데 그렇다고 쌩 코드로 쓰자니 이것도 조금 부담스러울 수 있죠.

 

예를 들어, 벡터 내적, 외적 코드를 짠다고 생각해 봅시다..

내적, 외적은 한 두줄로 끝나지만, 해당 코드를 척 봤을 때

이 코드가 외적인지 내적인지 아니면 다른 연산인지.. 헷갈리는 경우가 많습니다.

근데, 함수로 만들어 가독성을 챙기자니 함수 오버헤드가 부담되기도 하죠

 

이럴 때 사용하는 게 inline 함수입니다.

 

inline 함수

인라인 함수는 함수 호출이 아니라

인라인으로 지정된 코드를 컴파일 이러가 그대로 옮겨 적는 것과 같습니다.

 

마치 전처리기의 #define 매크로와 동일한 역할을 하는 것이죠.

 

참고) inline vs 매크로

- 매크로는 디버깅하기 힘들다!

  -> 매크로는 호출스택에 올라가지 않는다.

  -> 매크로는 중단점 설정이 불가능하다.

 

- 매크로는 항상 글로벌하다.

  -> 객체 지향적으로 사용하기에는 조금 어렵다.

 

- 매크로는 전처리기에서 해주지만, inline 함수는 컴파일러가 해준다.

 

이러한 특성 때문에, 특별한 경우가 아니라면 inline 함수로 처리해 주는 것이 좋습니다.

 

1. inline 함수의 특징

- 어떤 함수든 앞에 inline 키워드를 붙이면 inline 함수로 만들 수 있다.

- 단, inline 키워드를 붙이더라도 inline처럼 동작하지 않을 수 있다.

   -> 컴파일러가 inline 함수로 만들기 적합하지 않을 경우 inline을 명시하더라도 만들지 않을 수도 있다.

- 또, 컴파일러가 inline으로 동작하면 좋을 것 같은 함수는 자동적으로 inline으로 처리한다.

 

즉, inline 키워드는 컴파일러에게 명시해 줄 뿐

반드시 inline 함수화 시킬 수 있는 것은 아니라는 것입니다.

 

2. inline 함수 구현시 주의점 

- 인라인함수는 분할 구현을 하지 말고 하나의 파일에 구현하자

- 간단한 함수만 inline으로 구현하자

   -> inline 함수는 그대로 함수의 바디 부분을 복사 붙여 넣기 하는 거서이기 때문에, 코드의 길이가 늘어나고

       실행파일의 크기를 증가시킨다.

       이것은 CPU 캐시가 효율적이게 동작하지 못하게 할 수 있다.

 

그러므로

은닉성을 위한 get함수, set함수

operator 함수

수학적인 공식 등

 

매우 간단한 1~2 줄짜리 코드나, oparetor 함수, 매크로로 만들면 좋을 법한 간단한 연산을

인라인 함수로 만드는 것이 좋습니다.

 

간단한 인라인 함수 시연

//간단한 벡터 구현
//STL vector 아닙니다.
class Vector
{
public:
	Vector() {}
	Vector(float y, float x) :_y(y), _x(x)
	{}

	inline Vector operator+(const Vector& other) const
	{
		return Vector(_y + other._y, _x + other._x);
	}

	inline Vector operator-(const Vector& other) const
	{
		return Vector(_y - other._y, _x - other._x);
	}

	inline void operator+=(const Vector& other)
	{
		_y += other._y;
		_x += other._x;
	}

	inline void operator-=(const Vector& other)
	{
		_y -= other._y;
		_x -= other._x;
	}

	inline float GetDistance(const Vector& other) const
	{
		return sqrt(GetPoweredDistance(other));
	}

	inline float GetPoweredDistance(const Vector& other) const
	{
		float y = y - other._y;
		float x = x - other._x;
		return y * y + x * x;
	}

	inline float GetDotProduct(const Vector& other) const
	{
		//내적
		return (_y * other._y) + (_x * other._x);
	}

public:
	float _y;
	float _x;
};

 

분할 구현은 안되지만

한 파일 내에서 따로 정의를 클래스 외부로 빼서

정의해도 됩니다.

'언어 > C, C++' 카테고리의 다른 글

[C++] 예외처리  (1) 2024.01.09
[C++] static 에 대해서  (1) 2024.01.08
[C++] 캐스팅 4총사  (1) 2024.01.08
[C++] 다형성  (0) 2024.01.07
[C++] 클래스 상속  (1) 2024.01.07