Quick Reference
inline은 호출을 반드시 펼치라는 명령이 아닙니다. 작은 헤더 유틸리티를 링크 충돌 없이 제공할 때는 보통 static inline을 쓰고, 여러 파일에서 공유하는 일반 함수는 선언과 정의를 분리합니다.
| 상황 | 기본 선택 | 이유 |
|---|---|---|
| 헤더의 짧은 계산 도우미 | static inline | 각 translation unit 안에 정의가 생겨 충돌을 피합니다. |
| 여러 파일이 호출하는 일반 함수 | header 선언 + 한 .c 정의 | 외부 심볼의 소유자가 하나로 정해집니다. |
| 전처리 전용 치환 | macro | #, ##, 조건부 컴파일은 함수로 대체할 수 없습니다. |
/* math_utils.h */
static inline int clamp_zero(int value) {
return value < 0 ? 0 : value;
}헤더와 linkage
static inline은 짧은 함수 본문을 헤더에 둘 때 가장 보수적인 패턴입니다. static이 internal linkage를 만들므로, 여러 .c 파일이 같은 헤더를 include해도 하나의 외부 함수 정의를 여러 번 만드는 문제가 생기지 않습니다.
/* score.h */
int score_for_level(int level);
/* score.c */
int score_for_level(int level) {
return level * 100;
}외부에서 공유할 API라면 위처럼 header에는 선언만 두고 .c 파일 하나에 정의를 둡니다. inline만 헤더에 두는 형태는 C의 external linkage 규칙과 별도 외부 정의 필요 여부가 얽히므로, 단순한 성능 목적으로 선택하지 않습니다.
매크로와 선택
#define SQUARE(x) ((x) * (x))
static inline int square_int(int value) {
return value * value;
}SQUARE(i++)는 인자를 두 번 평가할 수 있지만, square_int(i++)는 인자를 한 번 평가합니다. 계산·비교 로직은 타입 검사와 디버깅이 가능한 static inline을 먼저 고릅니다.
다만 static inline도 타입별로 하나씩 작성해야 합니다. 여러 타입을 하나의 API로 처리해야 한다면 제네릭 선택이나 별도 API 설계를 검토하고, 매크로로 숨기기 전에 각 타입의 결과와 overflow 정책을 확인합니다.
주의할 점
inline은 컴파일러의 최적화 선택과 별개입니다. 호출이 실제로 펼쳐질지 보장하지 않습니다.- 큰 함수나 재귀 함수에 붙인다고 성능 문제가 해결되지 않습니다. 병목은 측정으로 확인합니다.
- header의
static inline함수는 각 translation unit에 내부 정의가 생길 수 있으므로, 함수 주소 비교나 단일 전역 상태가 필요한 API에는 맞지 않을 수 있습니다. extern inline은 표준·compiler mode에 따라 해석 차이가 얽히기 쉬우므로, 특별한 이유가 없으면 header 선언 + 한 .c 정의를 사용합니다.
참고 링크
2 sources