몇 가지 설명. 첫 번째는 일반적이고 두 번째는 매개 변수가있는 C 전 처리기 매크로에 고유합니다.
흐름 제어
나는 이것이 일반 C 코드에서 사용되는 것을 보았습니다. 기본적으로 goto의 안전한 버전입니다. 탈출 할 수 있고 모든 메모리가 제대로 정리되기 때문입니다.
goto같은 것이 좋은 이유는 무엇 입니까? 글쎄, 거의 모든 줄이 오류를 반환 할 수있는 코드가 있지만 모든 줄에 동일한 방식으로 반응해야하는 경우 (예 : 정리 후 호출자에게 오류를 전달하여) 일반적으로 if( error ) { /* cleanup and error string generation and return here */ }as 를 피하는 것이 더 읽기 쉽습니다. 정리 코드의 중복을 방지합니다.
그러나 C ++에서는 정확히 이러한 목적으로 예외 + RAII가 있으므로 잘못된 코딩 스타일로 간주합니다.
세미콜론 검사
함수와 같은 매크로 호출 후 세미콜론을 잊어 버리면 인수가 원하지 않는 방식으로 축소되어 유효한 구문으로 컴파일 될 수 있습니다. 매크로를 상상해보십시오
#define PRINT_IF_DEBUGMODE_ON(msg) if( gDebugModeOn ) printf("foo");
그것은 실수로 다음과 같이 불립니다.
if( foo )
PRINT_IF_DEBUGMODE_ON("Hullo\n")
else
doSomethingElse();
는 "다른"은과 관련된 것으로 간주 될 gDebugModeOn때, foo이다 false의 정확한 일어날 의도 무슨 역.
임시 변수에 대한 범위 제공.
do / while에는 중괄호가 있으므로 임시 변수에는 이스케이프 할 수없는 명확하게 정의 된 범위가 있습니다.
"원치 않는 세미콜론"경고 방지
일부 매크로는 디버그 빌드에서만 활성화됩니다. 다음과 같이 정의합니다.
#if DEBUG
#define DBG_PRINT_NUM(n) printf("%d\n",n);
#else
#define DBG_PRINT_NUM(n)
#endif
이제 조건부 내 릴리스 빌드에서 이것을 사용하면 다음과 같이 컴파일됩니다.
if( foo )
;
많은 컴파일러는 이것을 다음과 같은 것으로 간주합니다.
if( foo );
종종 실수로 작성됩니다. 그래서 당신은 경고를받습니다. 가 할 {} (거짓)은 컴파일러에서이 숨 깁니다, 그리고 당신이 있다는 표시로 인정되는 동안 정말 여기에 아무것도하지 않고 싶다.
조건문에 의한 줄 캡처 방지
이전 예의 매크로 :
if( foo )
DBG_PRINT_NUM(42)
doSomething();
이제 디버그 빌드에서 우리는 습관적으로 세미콜론을 포함했기 때문에 잘 컴파일됩니다. 그러나 릴리스 빌드에서는 갑자기 다음과 같이 바뀝니다.
if( foo )
doSomething();
또는 더 명확한 형식
if( foo )
doSomething();
의도 한 것이 전혀 아닙니다. 매크로 주위에 do {...} while (false)를 추가하면 누락 된 세미콜론이 컴파일 오류로 바뀝니다.
OP에 대한 의미는 무엇입니까?
일반적으로 오류 처리를 위해 C ++에서 예외를 사용하고 매크로 대신 템플릿을 사용하려고합니다. 그러나 매크로가 여전히 필요하거나 (예 : 토큰 붙여 넣기를 사용하여 클래스 이름을 생성 할 때) 매우 드문 경우 또는 일반 C로 제한되는 경우 이것은 유용한 패턴입니다.