C전처리와 빌드

매크로와 부작용

함수처럼 보이지만 단순 치환인 매크로가 왜 위험할 수 있는지와, 괄호와 부작용을 어떤 관점으로 봐야 하는지 정리합니다.

마지막 수정 2026년 3월 22일

기본 패턴

c
#define SQUARE(x) ((x) * (x))

설명

  • C 매크로는 함수 호출이 아니라 전처리 단계의 텍스트 치환입니다. 그래서 겉보기 문법은 비슷해도, 실제 동작은 함수와 전혀 다를 수 있습니다.
  • 가장 흔한 문제는 괄호 부족과 부작용 중복 평가입니다. 예를 들어 SQUARE(a + b)SQUARE(i++) 같은 입력은 사람이 기대한 것과 다른 코드로 확장될 수 있습니다.
  • 그래서 함수형 매크로를 쓸 때는 매개변수 전체와 결과 전체를 괄호로 감싸는 습관이 거의 필수입니다. 그래도 중복 평가 문제는 완전히 없어지지 않습니다.
  • 이 때문에 단순 상수, 조건부 컴파일, 아주 낮은 수준의 generic-like 패턴이 아니라면 매크로보다 static inline 함수가 더 안전한 경우도 많습니다.
  • 전처리는 C의 강력한 도구이지만, 컴파일러가 타입과 부작용을 충분히 이해하기 전 단계에서 개입한다는 점이 핵심입니다. 그래서 "편리하다"보다 "얼마나 예측 가능한가"를 먼저 봐야 합니다.

빠른 정리

항목의미
매크로전처리기의 텍스트 치환
괄호 규칙인자와 전체식을 충분히 괄호로 감싸기
위험중복 평가, 연산자 우선순위 문제
대안const, enum, static inline 함수

주의할 점

#define MAX(a, b) ((a) > (b) ? (a) : (b)) 같은 매크로에 i++를 넣으면 증가가 여러 번 일어날 수 있습니다. 부작용이 있는 표현식은 매크로 인자로 넘기지 않는 편이 안전합니다.

참고 링크

2 sources