
💡단순한 상수를 쓸 때는 #define보다 const 객체, 혹은 enum을 우선 생각합시다!
💡 함수처럼 쓰이는 매크로를 만들려면, #define 매크로보다 인라인 함수를 우선 생각하자!
◆ 매크로를 피해야 하는 이유
#define ASPECT_RATIO 1.653 -- A
const double AspectRatio = 1.653; -- B
Case A 경우
컴파일러에게 넘어가기 전에 선행 처리자가 밀어버리고 숫자 상수로 변경한다.
문제점
1. ASPECT_RATIO라는 이름은 커파일러가 쓰는 기호 테이블에 들어가지 않으므로,
에러메세지에 ASPECT_RATIO 이 아닌 1.653이 들어간다.
즉, 기호식 디버거에 나타나지 않는다.
2. 코드에서 ASPECT_RATIO 는 1.653으로 모두 변경이 되면서 해당 숫자의 사본이 등장하는 횟수 만큼 생성이 됩니다.
결과적으로 최종 코드의 크기가 커질 수 있다.
Case B 경우
1.653의 사본은 딱 한 번 생성하여 최종 코드의 크기가 작아진다.
또한, 컴파일러의 기호 테이블에도 들어가며, 디버거에 나타난다.
상수 정의 시 주의해야할 부분
- 상수 포인터를 정의하는 경우
포인터와 포인터가 가리키는 대상까지 const로 선언해줘야 한다!
-> const를 2번 써야 한다 - 클래스 상수를 정의하는 경우
어떤 상수의 유효범위를 클래스로 한정하고자 할 때는 그 상수를 멤버로 만들어야 한다.
그 상수의 사본 개수가 한 개를 넘지 못하게 하고 싶다면? static 멤버로 만들어야 한다.
정적 멤버로 만들어지는 정수 타입의 클래스 내부 상수는 보통 정의를 해주지 않아도 된다.
하지만 예외가 있다. 클래스 상수의 주소를 구하는 경우와 컴파일러가 정의를 요구하는 경우.
클래스 상수의 정의는 cpp에 둔다.
정의 시 상수의 초기값이 있으면 안된다. -> 클래스 상수는 생성과 동시에 초기화되어버리기 때문에..
// header
class GamePlayer {
private: static const int NumTurns = 5; // 상수 선언 (정의 X)
int scores[NumTurns]; // 상수 사용
}
// cpp
const int GamePlayer::NumTurns; // 정의
◆ 나열자 둔갑술
class GamePlayer {
private: enum { NumTurns = 5 }; // "나열자 둔갑술" -> 상수처럼 사용
int scores[NumTurns]; // NumTurns를 배열 크기로 사용
};
Q. 왜 enum을 사용할까?
- 배열 크기나 상수표현식의 위치에서 사용이 가능
- enum의 값은 컴파일 타임에 결정되므로 배열 크기로 문제없이 사용 가능
- 매크로 보다 안전
Q. 왜 const는 안될까?
배열의 크기는 컴파일 타임 상수여야 하는데 const는 런타임 상수로 간주되어 컴파일 에러가 발생할 수 있음
C++11부터는 이런 해결책으로 constexpr을 사용하여 같은 효과를 얻을수 있음
class
GamePlayer
{
private:
static constexpr int NumTurns = 5; // ✅ 컴파일 타임 상수
int scores[NumTurns]; // ✅ 컴파일 타임에 평가됨 -> 배열 크기로 사용 가능
};
◆ 매크로 함수를 피해야하는 이유?
함수 호출 오버헤드를 일으키지 않도록 매크로 함수를 사용하는 경우가 있다.
오버헤드란?

// a와 b 중 더 큰 것을 f에 넘겨 호출하는 매크로함수
#define CALL_WITH_MAX(a,b) f((a) > (b) ? (a) : (b))
int a = 5, b = 0;
CALL_WITH_MAX(++a, b); // a가 더 큼 -> a 2번 호출 -> a 2번 증가
CALL_WITH_MAX(++a, b + 10); // b가 더 큼 -> a 1번 호출 -> a 1번 증가
매크로 부작용에 대한 코드 예시이다.
-> 이를 해결하기 위해 아래와 같이 템플릿 인라인 함수를 사용한다.
template<typename T>
inline void CallWithMax(const T& a, const T& b)
{
f(a > b ? a : b);
}
템플릿 인라인 함수로 사용시 함수 호출 오버헤드가 발생하지 않고 매크로의 부작용 없이 안전하게 사용할 수 있다.
배운점
- 선언과 정의의 차이점을 명확하게 이해
- #define과 const을 정확히 이해
- enum const constexpre에 대한 이해
- 오버헤드, 매크로함수, 인라인함수에 대한 이해
'IT > C++' 카테고리의 다른 글
| [C++] Modern C++ 11/14 핵심 내용 정리 (2) | 2025.08.25 |
|---|---|
| [C++] C++ 표준화 버전 정리 (0) | 2025.03.16 |
| [Effective C++] 항목 1 : C++을 언어들의 연합체로 바라보는 안목은 필수 (0) | 2025.02.07 |