`fallthrough` 속성

fallthrough 속성 (C23)

switch 문 안에서 case 라벨 뒤에 break를 빠뜨리면 다음 case로 흘러 내려가는(fallthrough) 일이 생겨요. 컴파일러는 이걸 버그로 의심해서 경고를 내기도 하는데, 가끔은 그 fallthrough가 의도적일 때가 있어요. 그럴 때 [[fallthrough]]를 쓰면 "이건 실수 아니라 일부러 넘어가는 거야"라고 컴파일러에게 알려줄 수 있어요.

출처: cppreference

본문

이전 case 라벨에서의 fallthrough가 의도된 것임을 나타내고, fallthrough에 경고를 내는 컴파일러가 이 부분을 진단하지 않도록 해요.

문법

[[fallthrough]] / [[__fallthrough__]]

설명

[[fallthrough]]는 속성 선언에만 써서 fallthrough 선언([[fallthrough]];)을 만들 수 있어요.

fallthrough 선언은 switch 문 안에서만 쓸 수 있고, 그 다음에 만나게 되는 다음 블록 항목(문, 선언, 라벨)이 그 switch 문의 case 또는 default 라벨이 붙은 문이어야 해요.

이전 case 라벨에서의 fallthrough가 의도된 것임을 나타내고, fallthrough에 경고를 내는 컴파일러가 이 부분을 진단하지 않도록 해요.

예시

switch 안에서 fallthrough가 의도적인 곳과 의도적이지 않은 곳을 구분해서 표시해봐요.

#include <stdbool.h>

void g(void) {}
void h(void) {}
void i(void) {}

void f(int n) {
  switch (n) {
    case 1:
    case 2:
      g();
     [[fallthrough]];
    case 3: // no warning on fallthrough
      h();
    case 4: // compiler may warn on fallthrough
      if(n < 3) {
          i();
          [[fallthrough]]; // OK
      }
      else {
          return;
      }
    case 5:
      while (false) {
        [[fallthrough]]; // ill-formed: no subsequent case or default label
      }
    case 6:
      [[fallthrough]]; // ill-formed: no subsequent case or default label
  }
}

int main(void) {}

눈여겨볼 점이 몇 개 있어요. case 3으로 넘어가는 fallthrough에는 [[fallthrough]];를 붙여서 경고를 꺼줬고, case 4처럼 표시하지 않은 곳은 컴파일러가 여전히 경고할 수 있어요. 또 case 5·case 6처럼 뒤에 case·default 라벨이 이어지지 않는 위치에 쓰면 잘못된 코드(ill-formed)예요. while(false) 안의 것은 문법적으로는 [[fallthrough]]로 보이지만 실행 경로가 없어서 역시 잘못된 사용이에요.

더 알아보기

  • [[fallthrough]]와 함께 자주 쓰는 [[deprecated]], [[maybe_unused]] 속성도 확인해 보세요.
  • switch 문의 구조는 switch 문서에서 다뤄요.
  • cppreference의 fallthrough 원문을 참고할 수 있어요.