본문 바로가기

Programming Languages/C++

[함수]-inline 함수

함수를 호출하는 과정에는 인수를 전달하고, 함수의 위치로 분기하며, 결과를 반환하고, 호출한 위치로 되돌아오는 동작이 수반된다. 이에 따른 처리시간 및 코드의 증가는 비록 미미한 것이지만, 때로는 매우 빠른 처리가 필요하여 불필요한 시간 지연을 피하고 싶을때가 있다. 특히 모듈의 크기가 매우 작아 모듈을 실행하는 시간이나 모듈 크기가 함수 호출에 따른 부수적인 시간 및 크드의 양과 큰 차이가 없고, 이 모듈을 매우 빈번히 호출한다면 함수를 사용하지 않는 것이 더 바람직할 수 있다.

inline 함수는 함수가 가지는 모듈화의 장점을 살리면서 이러한 불필요한 실행 효율 저하를 막기 위해 사용할 수 있다. inline 함수를 작성하는 것은 inline 키워드를 사용하는 것 외에는 일반 함수와 동일하다. 그러나 컴파일러가 번역할 때에는 일반 함수와는 달리 함수의 처리 문장이 호출되는 위치에 직접 삽입된다. 이렇게 번역하면 함수 호출 명령이 생략되어 호출에 따른 부수적 동작이 생략된다. 뿐만 아니라 일반 함수를 사용할 때에는 코드 최적화 단계에서 호출 루틴으로부터 함수로 넘어가는 부분에 대한 코드 최적화는 이루어지지 않지만, inline 함수를 사용하면 이 부분에 대한 코드 최적화도 이루어질 수 있다. 따라서 inline 함수를 사용하면 원시 프로그램은 함수를 사용한 간결하고 이해하기 쉬운 형태를 그대로 유지하며서 함수 호출에 따른 실행 효율 저하는 발생하지 않는다. 또한 인수 전달이나 반환값 전달 등을 위한 코드가 줄어들기 때문에 함수가 매우 짧은 경우에는 번역된 프로그램의 크기가 작아질 수 있다.

[소스코드 3-10]의 프로그램은 이전 참조 호출 내용에서 작성한 SwapInt.cpp와 동일하나 함수 SwapValues()가 inline으로 선언되어 있다. 이 경우 컴파일 과정에서 if (a < b) SwapValues(a, b); 코드의 위치에서 함수의 처리문장이 직접 삽입된 것처럼 번역된다.

// 소스코드 3-10 : SwapInline.cpp

#include <iostream>
using namespace std;
void SwapValues(int& x, int& y); // 원형

// 두 변수의 값을 바꾸는 함수 
// 인수 int &x, int &y : 값을 바꿀 변수
// 반환 : 없음
inline void SwapValues(int& x, int& y) {
	int temp = x;
	x = y;
	y = temp;
}

int main() {
	int a, b;
	cout << "두 수를 입력하세요 : ";
	cin >> a >> b;
	if (a < b) SwapValues(a, b); // 순서를 바꿔 a에 큰 값을 넣음
	cout << "큰 수 = " << a << " 작은 수 = " << b << endl;
	return 0;
}

주의할 것은 inline으로 함수를 선언하더라도 그 함수가 반드시 inline으로 번역된다는 것은 아니다. 컴파일러는 다음과 같은 경우 inline을 무시하고 일반 함수와 같이 번역한다.

  • 함수가 너무 큰 경우
  • 순환 호출(어떤 함수가 직접 또는 간접적으로 자기 자신을 호출하는 것)을 하는 경우 ex) 재귀함수
  • 프로그램 내에서 그 함수에 대한 포인터를 사용하는 경우

inline ㅎ마수는 #define 지시어로 정의하는 매크로와 비슷한 기능을 하고 있다. 그러나 이들 사이에는 다음과 같은 몇 가지 중요한 차이가 있다.

  • inline 함수는 일반 함수와 같이 인수 및 반환값에 대한 엄밀항 자료형 검사를 한다. 
  • inline 함수는 일반 함수와 동일한 문법을 따른다. 
  • inline 함수에 전달되는 인수들은 그 값을 한 번만 구한다. 매크로의 경우, 때에 따라서는 의도한 바와 다르게 인수의 값을 여러 번 구함으로써 잘못된 결과를 내기도 한다.

inline 함수의 선언 위치

일반 함수는 선언과 함께 함수의 정의가 이루어지는 것이므로, 한 프로젝트 내에서는 1회만 선언한다. 만일 여러 개의 소스 프로그램 파일에서 호출해야 한다면 함수의 선언은 1회만 하고 나머지 파일에는 함수의 원형만 선언한다. 그러나 inline 함수의 선언은 함수의 정의가 이루어지는 대신 호출 위치에 하수의 처리 문장이 삽입된다. 따라서 inline 함수는 그 함수를 사용하는 C++ 소스 프로그램 파일마다 선언해야 한다. 즉, f()라는 함수가 inline 함수이고, 이 함수를 한 프로젝트 내에 포함된 a.cpp와 b.cpp라는 두 소스 프로그램에서 호출하게 되어 있다면 동일한 내용을 a.cpp와 b.cpp에 모두 선언하여야 한다.