커널 헤더에 “:-!!”는 뭘 하는 코드인지 아시는 분?

조회수 2365회

/usr/include/linux/kernel.h에서 갖고 온 코드입니다

소스코드

/* Force a compilation error if condition is true, but also produce a
   result (of value 0 and type size_t), so the expression can be used
   e.g. in a structure initializer (or where-ever else comma expressions
   aren't permitted). */
#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); }))

여기서 :-!!는 뭔 하는 건지 모르겠습니다. true/false를 확인하는데 왜 !가 아니라 !!를 썼을까요?

1 답변

  • 좋아요

    0

    싫어요
    채택 취소하기

    이건 e의 값이 0으로 매겨질 수 있는지 확인하고, 만약 0이 될 수 없다면 빌드과정에서 실패하게 만드는 코드입니다.

    개인적으로는 매크로 이름이 ...ON_ZERO가 아니라 BUILD_BUG_OR_ZERO라고 하면 더 정확한 표현일 듯합니다.

    이 코드 sizeof(struct { int: -!!(e); }))는 읽을 때

    1. (e): expression e를 계산
    2. !!(e): 논리 not연산자(!)를 두 번씌움. e가 0이면 0, 아니면 1
    3. -!!(e): 단항 부정 연산자(-)를 씌움. e가 0이면 0, 아니면 -1
    4. struct{int: -!!(0);} --> struct{int: 0;}: 3의 결과가 0이었다면 멤버 anonymous bitfield가 0인 struct를 선언
    5. struct{int: -!!(1);} --> struct{int: -1;}: 3의 결과가 0이 아니라면 anonymous bitfield가 -1인 struct를 선언해 실패.

    assert()를 쓴다면 더 보기 좋은 코드가 됐겠지만 assert()를 쓰지 않고 이렇게 한 이유는 assert()는 런타임 테스트에서 오류를 잡을 수 있는 반면, 이 매크로는 그보다 일찍, 컴파일 테스트에서 오류를 잡을 수 있기 때문입니다.

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)