C 언어에서 매크로 정의 (#define) 시do{}while (0) 의 가치

2414 단어
최근 새 회사의 코드에서 도처에 do{...}가 사용되고 있는 것을 발견하였다.while(0), 구글을 살펴보니 Stack Overflow에 일찍이 많은 토론이 있었고 토론을 총괄했고 자신의 이해를 더한 것을 발견했다.do {...}while(0)의 가치는 주로 다음과 같다.
1. 코드의 적응성 증가
다음 매크로 정의는 do 를 사용하지 않았습니다.while(0)
#define FOO(x) foo(x); bar(x);

이렇게 매크로를 정의하면 개별적으로 호출해도 문제가 발생하지 않습니다. 예를 들어,
FOO(100)

매크로를 확장하면 다음이 됩니다.
foo(x);bar(x);

이렇게 FOO를 호출하는 것은 아무런 문제가 없지만 FOO (x) 는 제어문에 넣을 수 없습니다. 예를 들어
if (condition)
    FOO(x);
else 
    ...;

매크로 확장 후
if (condition)
    foo(x);bar(x);
else 
    ...;

이렇게 해서 문법 오류를 초래했다. 문법 오류는 무섭지 않다. 컴파일 단계에서 발견할 수 있다. 더욱 치명적인 것은 그가 논리 오류를 초래할 수 있다는 것이다. 이런 오류를 컴파일러가 발견할 수 없다. 이런 문제가 발생하면 프로그래머는 미치겠지.예를 들면 다음과 같습니다.
if (condition)
    FOO(x);

이 코드는 다음과 같이 확장됩니다.
if (condition)
    foo(x); bar(x);

이렇게 하면 condition이true든false든bar(x)는 모두 호출됩니다.이 고생한 형제 없나요?
이때while(0)의 가치가 구현되었습니다. FOO의 정의를 수정하십시오.
#define FOO(x) do { foo(x); bar(x); } while (0)

이렇게 FOO를 제어문에 넣으면 문제가 없다.
아마도 누군가가 말하기를:foo(x);bar(x)는 괄호로 묶으면 되지 않습니까?예를 들어 다음과 같이 정의합니다.
#define FOO(x) { foo(x); bar(x); }

다음 코드를 다시 보십시오.
if (condition)
    FOO(x);
else 
    ...;

확장:
if (condition)
    {foo(x);bar(x);} ; //
else 
    ...;

그대로 문법이 틀렸다.
2. 코드의 확장성 증가
내가 이해하는 확장성은 주로 매크로 정의에서 다른 매크로를 인용할 수 있다는 것이다. 예를 들어 다음과 같다.
#define FOO(x) do{OTHER_FOO(x)} while(0)
       OTHER_FOO          ,       

3. 코드의 유연성 증가
유연성은 주로 우리가 매크로에서break를 나올 수 있다는 데 나타난다. 예를 들어 다음과 같은 정의가 있다.
#define FOO(x)  do{ \
    foo(x);  \
    if(condition(x)) \
        break; \
    bar(x) \
    ..... \
} while(0)

좋은 웹페이지 즐겨찾기