매크로함수

매크로 함수의 기본적인 사용법은

#define FunctionName(Arg) 치환할것

여기서 보통 우리가 함수를 정의하는 방법은

return_type FunctionName(Arg){ …함수설명… } 과 같은 형식였다.
그런데 굳이 매크로함수에서는 함수가 어떤 동작을 할 것인지를 설명하는 부분이 치환할것 이라고 적어놓았다. 이 부분에 주목해서 매크로함수를 이해해야한다. 매크로함수는 기본적으로 런타임이 아니라 컴파일 타임에 FunctionName()이 불려진 부분을 치환할것으로 치환해주는 것이다. 만약 우리가 매크로함수를

#define myMacro(i) i*2

로 정의를 해놓고,

int i = myMacro(2);

라고 메인함수에서 실행한다고 생각해보면 실제로는 컴파일 타임에 컴파일러가 우리가 정해놓은 myMacro함수를 치환하여

int i = 2*2 ;

으로 치환을 하게 되는 것이다. 이를 조금 더 응용하게 되면 다음과 같은 매크로함수도 정의할 수 있다.

#define printValue(var) std::cout<<#var" = "<<var<<std::endl;

이러한 매크로함수를 만들수있는데, 여기서 #var의 의미는 var를 문자화 시키라는 의미이다.

int i = myMacro(2);
printValue(i);

를 출력하게 되면 i = 4

라는 결과를 얻을 수 있다.
매크로 함수를 적절하게 사용하는것은 중요하다. 그런데 꼭 주의해야할 점이 있는데 다음 코드를 예로 들어서 설명해 보겠다.

#define myMacro(i) i*2
int main()
{
    int i = myMacro(4+1);
}

과 같은 식으로 매크로 함수를 불럿다 치자. 우리가 원하는 결과는

i = 5*2 = 10

즉 i = 10이 되기를 원했을 것이다. 그런데 실제로 코드를 실행해보면

i =6

이라는 결과가 나오게 된다. 왜 이런일이 발생했을까?
바로 매크로함수는 치환 만 해주기 때문이다. 즉

int i = 4+1*2 ; 

라고 치환이 될 뿐이다. 우리가 진짜로 원하는 결과를 얻기 위해서는

#define myMacro(i) (i*2)

라고 괄호를 쳐주면 얻을 수 있게된다.
마지막으로 #var 오퍼레이터가 var을 들어온 문자열로 치환해버리는 것이였는데 매크로 연산자 중에서 ## 연산자도 있다. 이것은 간단한 코드로 살펴보면

#define myMacro2(a, b) a##b
int main()
{
    int myMacro2(aoi,sora) = 10;
}

를 돌려보게 되면 실제로 컴파일 타임에

int aoisora = 10;

라는 변수로 정의가 되는 것이다.

  • 따라서 매크로 함수는 컴파일 타임에 우리가 정의해놓은 치환값으로 치환해주는것 이라고 결론 지을 수 있다.