do {...} while (0) 의 의미 와 용법 (회전)

8265 단어
원본 주소:http://www.spongeliu.com/415.html
Liux 커 널 과 다른 오픈 소스 코드 에서 이러한 코드 를 자주 만 날 수 있 습 니 다.
do{
 ...
}while(0)

이런 코드 는 딱 봐 도 순환 이 아 닙 니 다. do. while 는 겉 으로 는 아무런 의미 가 없습니다. 그런데 왜 이렇게 사용 합 니까?
실제로 do {...} while (0) 의 역할 은 코드 를 미화 하 는 것 보다 훨씬 큽 니 다.자 료 를 좀 찾 아 보 았 는데, 총괄 적 으로 이렇게 쓰 면 주로 다음 과 같은 몇 가지 장점 이 있다.
1. 복잡 한 매크로 를 보조 적 으로 정의 하고 인용 할 때 오류 가 발생 하지 않도록 합 니 다.
예 를 들 어 이러한 매크로 를 정의 해 야 한다 고 가정 합 니 다.
#define DOSOMETHING()\
               foo1();\
               foo2();

이 매크로 는 DOSOMETHING () 을 호출 할 때 함수 foo 1 () 과 foo 2 () 가 호출 된다 는 뜻 입 니 다.하지만 호출 할 때 이렇게 쓰 면:
if(a>0)
    DOSOMETHING();

매크로 는 미리 처리 할 때 바로 펼 쳐 지기 때문에 실제로 쓴 코드 는 다음 과 같 습 니 다.
if(a>0)
    foo1();
foo2();

a 가 0 보다 크 든 안 크 든 foo 2 () 가 실 행 돼 프로그램 에 오류 가 발생 하기 때문이다.
그럼 {} 을 사용 하여 foo 1 () 과 foo 2 () 만 싸 도 될까요?
우 리 는 코드 를 쓸 때 문장의 오른쪽 에 점 수 를 붙 이 는 것 에 익숙 합 니 다. 매크로 에서 {} 을 사용 하면 코드 에 이렇게 쓰 는 것 과 같 습 니 다. "{...};" 펼 친 후에 바로 이 모양 입 니 다.
if(a>0)
{
    foo1();
    foo2();
};

이렇게 하면 심지어 번역 이 통과 되 지 않 을 것 이다.그래서 많은 사람들 이 do {...} while (0) 를 사 용 했 습 니 다.
#define DOSOMETHING() \
        do{ \
          foo1();\
          foo2();\
        }while(0)\
    
...
 
if(a>0)
    DOSOMETHING();
 
...

이렇게 해야만 매크로 가 펼 쳐 진 후에 야 최초의 의 미 를 보존 할 수 있다.GCC 는 do {...} while (0) 대신 Statement - expressions 를 제공 합 니 다.그래서 매크로 를 이렇게 정의 할 수 있 습 니 다.
#define DOSOMETHING() ({\
        foo1(); \
        foo2(); \
})

http://www.spongeliu.com/ 2. goto 를 사용 하여 프로그램 흐름 을 통일 적 으로 제어 하 는 것 을 피한다.
일부 함수 에서 함수 return 전에 우 리 는 항상 마무리 작업 을 합 니 다. 예 를 들 어 free 에서 함수 하 나 를 떨 어 뜨리 고 malloc 의 메모 리 를 시작 합 니 다. goto 는 비교적 간편 한 방법 입 니 다.
int foo()
{
    somestruct* ptr = malloc(...);
 
    dosomething...;
    if(error)
    {
        goto END;
    }
 
    dosomething...;
    if(error)
    {
        goto END;
    }
    dosomething...;
 
END:
    free(ptr);
    return 0;
 
}

goto 는 소프트웨어 공학 의 구조 화 에 부합 되 지 않 고 코드 를 이해 하기 어 려 울 수 있 기 때문에 많은 사람들 이 사용 을 제창 하지 않 습 니 다. 이 럴 때 do {} while (0) 로 통일 적 인 관 리 를 할 수 있 습 니 다.
int foo()
{
 
    somestruct* ptr = malloc(...);
 
    do{
        dosomething...;
        if(error)
        {
            break;
        }
 
        dosomething...;
        if(error)
        {
            break;
        }
        dosomething...;
    }while(0);
 
    free(ptr);
    return 0;
 
}

여기 서 함수 주 체 를 do () while (0) 로 포함 시 키 고 break 를 사용 하여 goto 를 대체 합 니 다. 후속 처리 작업 은 while 이후 에 똑 같은 효 과 를 얻 을 수 있 습 니 다.
 
3. 빈 매크로 가 일 으 키 는 warning 을 피한다.
커 널 에 서 는 서로 다른 구조의 제한 으로 인해 빈 매크로 를 사용 하 는 경우 가 많 습 니 다. 컴 파일 할 때 빈 매크로 는 warning 을 제공 합 니 다. 이러한 warning 을 피하 기 위해 do {} while (0) 를 사용 하여 빈 매크로 를 정의 할 수 있 습 니 다.
#define EMPTYMICRO do{}while(0)

 
4. 하나의 단독 함수 블록 을 정의 하여 복잡 한 조작 을 실현 합 니 다.
기능 이 복잡 하고 변수 가 많 으 며 함 수 를 추가 하고 싶 지 않 을 때 do {} while (0) 를 사용 하 십시오.코드 를 안에 쓰 면 변수 이름 이 함수 이전 이나 그 후의 중복 을 고려 하지 않 고 변 수 를 정의 할 수 있 습 니 다.

좋은 웹페이지 즐겨찾기