매크로는 전처리 기가 진짜 코드에 넣을 복사 / 붙여 넣기 텍스트입니다. 매크로의 저자는 교체가 유효한 코드를 생성하기를 희망합니다.
성공하려면 세 가지 좋은 "팁"이 있습니다.
매크로가 진짜 코드처럼 동작하도록 도와주세요
보통 코드는 일반적으로 세미콜론으로 끝납니다. 사용자가 코드를 필요로하지 않으면 ...
doSomething(1) ;
DO_SOMETHING_ELSE(2) // <== Hey? What's this?
doSomethingElseAgain(3) ;
이는 세미콜론이없는 경우 사용자가 컴파일러에서 오류를 생성 할 것으로 예상 함을 의미합니다.
그러나 진짜 좋은 이유는 매크로 작성자가 매크로를 실제 함수 (아마도 인라인)로 대체해야 할 수도 있기 때문입니다. 따라서 매크로는 실제로 하나처럼 동작 해야 합니다.
따라서 세미콜론이 필요한 매크로가 있어야합니다.
유효한 코드를 생성하십시오
jfm3의 답변에 표시된 것처럼 때로는 매크로에 둘 이상의 명령어가 포함되어 있습니다. 매크로가 if 문 내에서 사용되면 문제가 될 것입니다.
if(bIsOk)
MY_MACRO(42) ;
이 매크로는 다음과 같이 확장 될 수 있습니다.
#define MY_MACRO(x) f(x) ; g(x)
if(bIsOk)
f(42) ; g(42) ; // was MY_MACRO(42) ;
의 g
값에 관계없이 기능이 실행됩니다 bIsOk
.
즉, 매크로에 범위를 추가해야합니다.
#define MY_MACRO(x) { f(x) ; g(x) ; }
if(bIsOk)
{ f(42) ; g(42) ; } ; // was MY_MACRO(42) ;
유효한 코드 생성 2
매크로가 다음과 같은 경우 :
#define MY_MACRO(x) int i = x + 1 ; f(i) ;
다음 코드에서 다른 문제가 발생할 수 있습니다.
void doSomething()
{
int i = 25 ;
MY_MACRO(32) ;
}
다음과 같이 확장되기 때문입니다.
void doSomething()
{
int i = 25 ;
int i = 32 + 1 ; f(i) ; ; // was MY_MACRO(32) ;
}
이 코드는 물론 컴파일되지 않습니다. 따라서 솔루션은 범위를 사용하고 있습니다.
#define MY_MACRO(x) { int i = x + 1 ; f(i) ; }
void doSomething()
{
int i = 25 ;
{ int i = 32 + 1 ; f(i) ; } ; // was MY_MACRO(32) ;
}
코드가 다시 올바르게 작동합니다.
세미콜론 + 스코프 효과를 결합 하시겠습니까?
이 효과를 생성하는 하나의 C / C ++ 관용구가 있습니다. do / while 루프 :
do
{
// code
}
while(false) ;
do / while은 범위를 생성하여 매크로의 코드를 캡슐화하고 끝에 세미콜론이 필요하므로 필요한 코드로 확장됩니다.
보너스?
C ++ 컴파일러는 사후 조건이 거짓이라는 사실이 컴파일 시간에 알려져 있기 때문에 do / while 루프를 최적화합니다. 이것은 다음과 같은 매크로를 의미합니다.
#define MY_MACRO(x) \
do \
{ \
const int i = x + 1 ; \
f(i) ; g(i) ; \
} \
while(false)
void doSomething(bool bIsOk)
{
int i = 25 ;
if(bIsOk)
MY_MACRO(42) ;
// Etc.
}
로 올바르게 확장됩니다
void doSomething(bool bIsOk)
{
int i = 25 ;
if(bIsOk)
do
{
const int i = 42 + 1 ; // was MY_MACRO(42) ;
f(i) ; g(i) ;
}
while(false) ;
// Etc.
}
그런 다음 다음과 같이 컴파일되고 최적화됩니다.
void doSomething(bool bIsOk)
{
int i = 25 ;
if(bIsOk)
{
f(43) ; g(43) ;
}
// Etc.
}
void
경우 끝에 ((void) 0) 과 같은 형식 표현식을 추가합니다 .