C 멀티 라인 매크로 : DO/WHING (0) 대 범위 블록 [중복
문제
가능한 복제물 :
매크로를 정의 할 때 (0) DO 사용은 무엇입니까?
C/C ++ 매크로의 경우 가끔 무의미한 행동/if/else 문이있는 이유는 무엇입니까?
(0) {…}?
나는 do/while (0) 루프와 같은 다중선 C 매크로를 보았습니다.
#define FOO \ do { \ do_stuff_here \ do_more_stuff \ } while (0)
기본 블록 사용과 달리 코드를 작성하는 이점 (있는 경우)은 무엇입니까?
#define FOO \ { \ do_stuff_here \ do_more_stuff \ }
해결책
http://bytes.com/groups/c/219859-do- while-0-macro-substitutions
Andrey Tarasevich :
'do/where'버전을 사용한다는 전체 아이디어는 복합 문으로가 아니라 정기적 인 진술로 확장되는 매크로를 만드는 것입니다. 이것은 모든 상황에서 일반 기능을 사용하여 기능 스타일 매크로를 균일하게 사용하기 위해 수행됩니다.
다음 코드 스케치를 고려하십시오
if (<condition>)
foo(a);
else
bar(a);
여기서 'foo'와 'bar'는 일반적인 기능입니다. 이제 기능 'foo'를 위의 자연의 매크로로 바꾸고 싶다고 상상해보십시오.
if (<condition>)
CALL_FUNCS(a);
else
bar(a);
이제 매크로가 두 번째 접근법 (Just '{'및 '}')에 따라 정의되면 코드는 더 이상 컴파일되지 않습니다. 'if'의 '진정한'지점은 이제 복합 문으로 표시되기 때문입니다. 그리고 당신이 a ';'를 넣을 때 이 복합 문자 후, 당신은 전체 'if'문을 완성하여 'else'브랜치를 고려합니다 (따라서 컴파일 오류).
이 문제를 해결하는 한 가지 방법은 넣지 말아야한다는 것을 기억하는 것입니다. ';' 매크로 "호출"후
if (<condition>)
CALL_FUNCS(a)
else
bar(a);
이것은 예상대로 컴파일하고 작동하지만 균일하지는 않습니다. 더 우아한 솔루션은 거시적이 화합물이 아닌 정기적 인 진술로 확장하는 것입니다. 이를 달성하는 한 가지 방법은 매크로를 다음과 같이 정의하는 것입니다.
#define CALL_FUNCS(x) \
do { \
func1(x); \
func2(x); \
func3(x); \
} while (0)
이제이 코드입니다
if (<condition>)
CALL_FUNCS(a);
else
bar(a);
아무런 문제없이 컴파일됩니다.
그러나 내 정의 사이의 작지만 중요한 차이점에 주목하십시오. CALL_FUNCS
그리고 메시지의 첫 번째 버전. 나는 넣지 않았다;
~ 후에 } while (0)
. a ;
그 정의가 끝날 때마다 'do/while'을 사용하는 전체 요점을 즉시 물리 치고 매크로가 화합물 진술 버전과 거의 동일하게 만들 것입니다.
원래 메시지에서 인용 한 코드의 저자가 왜 이것을 넣었는지 모르겠습니다. ;
~ 후에 while (0)
. 이 형식에서는 두 변형이 모두 동일합니다. 'do/while'버전을 사용하는 모든 아이디어는이 마지막을 포함하지 않습니다. ;
매크로로 (위에서 설명한 이유 때문에).