inline

김펭귄·2025년 7월 25일

C++

목록 보기
11/20

inline

  • 함수 호출부를 함수 코드로 대체하는 작업

  • 동일 정의가 여러 번 포함돼도 링크 오류가 나지 않도록 ODR(One Definition Rule) 예외를 부여하는 기능

  • C++17부터는 전역변수나 멤버 변수 등에 사용하는 기능이 추가됨

inline 함수

  • 함수 선언부나 정의부에 inline 키워드를 붙여 사용 (보통 정의부에)
inline int min(int x, int y)
{
    return (x < y) ? x : y;
}

int main()
{
    std::cout << min(5, 6) << '\n';
}
  • inline 키워드는 컴파일러에게 호출 지점에 함수 코드를 직접 붙여 넣으라고 지시. 함수를 호출하면서 발생하게 되는 오버헤드를 제거해도 된다는 제안을 함
    따라서 아래와 같이 컴파일러가 함수 정의부를 삽입함
int main()
{
    std::cout << ((5 < 6) ? 5 : 6) << '\n';
}

동작 과정

  1. 컴파일 단계

    • 컴파일러는 inline 요청을 받으면 함수 본문을 호출 지점에 삽입할지 여부를 성능/비용을 분석하여 판단
    • 함수 정의부가 작을수록 삽입 가능성이 높다
  2. 링크 단계

    • 동일한 inline 함수 정의가 여러 번 등장해도 링커가 에러 안 나도록 함

inline 함수의 장점

  • 같은 translation unit에 함수/변수가 중복 정의되어 있어도 같은 것으로 치고 에러 발생 안 시킴. 단, 동일한 정의부여야 함

  • 따라서 헤더파일에서 inline으로 정의하고 여러 파일에서 include해도 문제 없음

// foo.hpp
inline int foo() { return 5; }

// foo.cpp
#include "foo.hpp"					// 헤더에서 정의부 가져오고

// main.cpp
#include "foo.hpp"					// 또 가져와도 OK
inline int foo() { return 5; }		// 근데 또 정의해도 OK
  • 함수를 호출하고 다시 caller로 돌아오는 과정에서의 overhead를 감소시킬 수 있다

  • 특히 위와 같이 함수(min())가 작고 많이 호출될 때 inline을 사용하면 효율적

inline 함수의 단점

  • 다른 translation unit에 있는 함수는 컴파일러가 볼 수 없으므로 사용 불가능

  • 함수 크기가 크면, 직접 삽입하면서 파일 크기도 커지고(cache hit 감소) overhead도 더 커짐

  • 부적절한 inline은 오히려 성능을 떨어뜨림

  • 따라서 현대 컴파일러는 inline을 대부분 무시.
    본인이 알아서 무엇이 더 효율적인지 판단하여 inline expansion 수행 (쓰지말자)

inline 전역변수

  • C++17에서 도입된 inline 전역 변수

  • inline 함수처럼 헤더 파일에서 직접 정의하여도 여러 개의 소스 파일에서 중복 정의(ODR 위반) 없이 단 하나의 실제 전역 변수로 인식됨

  • 선언과 정의를 분리하는 번거로움이 없고, 헤더 파일 하나만 수정하면 전체 프로그램에서 동시 반영됨

  • constexpr도 external linkage 가능

사용법

  • extern 대신 inline사용하여 헤더파일에서 정의하면 된다
// config.hpp
#pragma once

// cpp파일에서 정의 없이 헤더에서 바로 선언 및 정의함
inline int g_counter = 5;             
inline constexpr int max_value = 100;      // constepxr도 가능
inline const double gravity = 9.8;         


// main.cpp
#include <iostream>
#include "config.hpp"

int main() {
	std::cout << g_counter;		// 5
	std::cout << max_value;		// 100
    std::cout << gravity;		// 9.8
}

inline 전역변수 정리

  • 헤더파일에서 정의하므로 cpp 파일도 필요 없음

  • main파일 뿐만 아니라 다른 파일에서 include하여 사용하여도 중복 정의되지 않고 하나의 전역 변수/상수처럼 동작함

  • inline 없이 이렇게 할 경우, 소스파일마다 같은 이름의 전역변수를 재정의하는 것이므로 inline을 꼭 사용해야함

  • extern을 사용한 전역변수의 값을 수정할 경우 해당 전역변수가 정의되어 있는 소스 파일(.cpp)만 재컴파일하면 되었다.
    하지만, inline을 사용한 전역변수의 값을 수정한 경우 해당 전역변수가 선언, 정의되어 있는 헤더파일(.hpp)을 include하는 모든 소스 파일(.cpp)을 전부 재컴파일 해야 한다

Reference

learncpp.com
learncpp.com

profile
반갑습니다

0개의 댓글