2013-04-24 6 views
5

나는 with 구문과 닮은 매크로를 찾고 있었다. 그것은 어떤 다른 목적을 위해 유용 할 수 있습니다"with with"macro with C

with (lock(&x), unlock(&x)) { 
    ... 
} 

: 사용은 같은 것을해야한다.

나는이 매크로를 내놓았다 :

#define __with(_onenter, _onexit, v) \ 
    for (int __with_uniq##v=1; __with_uniq##v > 0;)\ 
     for (_onenter; __with_uniq##v > 0; _onexit) \ 
      while (__with_uniq##v-- > 0) 

#define _with(x, y, z) __with(x, y, z) 
#define with(_onenter, _onexit) _with(_onenter, _onexit, __COUNTER__) 

그것은해야하기 때문에 3 개 중첩 루프가 :

  • 아마도 변수 _onenter를 초기화 (C99 만, 물론)

    1. 초기화 루프 카운터를 (예 : with (int fd=open(..), close(fd)))
    2. 코드 블록 내에 break을 허용합니다.

    나는 XV6의 OS의 코드에 그것을 사용하고 매우 유용 할 것 같습니다 (continue도 허용된다. 그리고 매크로 assert()에 그것을 밖으로 조정될 수 있습니다).

    제 질문은 - 매크로와 관련된 최악의 문제는 무엇입니까? C 매크로 (단순한 새로운 제어 흐름 구조를 구현하는 매크로)의 단순한 사용 외에도 말입니다.

    지금까지 이러한 단점/문제를 발견 :

    1. return 또는 goto (예 : fd < 0 등) 오류
    2. 지원하지 않습니다 (하지만 커널 코드의 일부 goto의를 절약 할 수 있습니다)에 대한 지원하지 않습니다. 나는 이것이 고칠 수 있다고 생각한다.
    3. gnu89/c99 이상 (루프 카운터. 고유 한 변수 트릭이 필요 없음)
    4. 단순한 잠금 해제보다 다소 효율적입니다. 나는 그것이 사소한 것이라고 생각한다.

    다른 문제가 있습니까? C에서 비슷한 구조를 구현하는 더 좋은 방법이 있습니까?

  • 답변

    6

    매크로가 나를 깜짝 놀라게합니다. traditional approach using gotos을 선호합니다.

    이러한 접근 방식은 원시적이지만 대부분의 C 프로그래머는 패턴에 익숙하며 그렇지 않은 경우 로컬 코드를 읽으면 이해할 수 있습니다. 숨겨진 동작이 없습니다. 결과적으로, 그것은 꽤 신뢰할 수 있습니다.

    매크로는 영리하지만 대부분의 사람들에게 새로운 것이므로 숨겨진 잡화가 있습니다. 새로운 참여자는 "with 블록으로 return 또는 goto을하지 말고" "break은 주변 루프가 아닌 with 블록에서 벗어날 것"과 같은 생각 규칙을 사용해야합니다. 나는 실수가 자주 일어날 것을 두려워한다.

    컴파일러에이 구문의 오용에 대한 경고를 추가 할 수 있으면 잔액이 변경됩니다. With clang, 옵션으로 보입니다. 이 경우 오용이 감지되고 코드는 다른 컴파일러로 이식 될 수 있습니다.

    자신을 GCC와 Clang으로 제한하려는 경우 cleanup 속성을 사용할 수 있습니다.그게 당신의 예는 다음과 같이 할 것 :이 범위를 벗어나면

    lock_t x = NULL __attribute__((cleanup(unlock))); 
    lock(&x); 
    

    그리고 unlock

    변수에 대한 포인터로 호출됩니다. 이것은 returngoto과 같은 다른 언어 기능과 통합 된 C/C++ 프로젝트의 예외가있는 경우에도 통합됩니다.

    +0

    오. 마지막 답변 ... 고맙습니다.'cleanup'에 대해 잘 모르겠습니다. 유용한 소리입니다. 매크로는 그 희소성 외에 더 구체적인 문제가 있습니까? – Elazar

    +1

    함수의 중간에'return' 문에 대한 엄격한 코딩 표준을 사용하지 않는다면'return'에 대한 지원이 부족한 것이 거래 차단기처럼 보입니다. 'with '블록의'return'은 눈에 띄지 않지만 런타임에는 혼란을 가져올 것이다. – pdw

    +0

    나는 '반환'이 큰 문제라는 것을 이해하고 동의한다. (그래서 '정리'가 훨씬 낫다.) 그러나 'goto'는 똑같이 엄격한 코딩 표준을 요구하지 않습니까? 이 점에서 goto의 장점은 무엇입니까? – Elazar