`maybe_unused` 속성

maybe_unused 속성 (C23)

컴파일러가 "이 변수 안 썼잖아" 하고 경고를 내는 경우가 있어요. 그런데 가끔은 일부러 안 쓰는 게 맞는 경우가 있어요. 예를 들어 릴리스 빌드에서 assert가 빠지면서 변수가 미사용이 된다거나, 인터페이스를 위해 받아두기만 하는 매개변수라거나요. 그럴 때 [[maybe_unused]]를 붙이면 그 엔티티에 대한 "미사용" 경고만 골라서 끌 수 있어요.

출처: cppreference

본문

미사용 엔티티에 대한 경고를 억제해요.

문법

[[maybe_unused]] / [[__maybe_unused__]]

설명

이 속성은 다음 엔티티의 선언에 쓸 수 있어요.

  • struct/union: struct [[maybe_unused]] S;
  • typedef 이름: [[maybe_unused]] typedef S* PS;
  • 객체: [[maybe_unused]] int x;
  • struct/union 멤버: union U { [[maybe_unused]] int n; };
  • 함수: [[maybe_unused]] void f(void);
  • 열거형: enum [[maybe_unused]] E {};
  • 열거자: enum { A [[maybe_unused]], B [[maybe_unused]] = 42 };

컴파일러가 미사용 엔티티에 대해 경고를 내는 상황이라면, maybe_unused로 선언된 엔티티에 대해서만 그 경고를 억제해요.

예시

디버그 모드에서는 쓰이다가 릴리스 모드에서 미사용이 되는 변수에 [[maybe_unused]]를 붙여봐요.

#include <assert.h>

[[maybe_unused]] void f([[maybe_unused]] _Bool cond1, [[maybe_unused]] _Bool cond2)
{
   [[maybe_unused]] _Bool b = cond1 && cond2;
   assert(b); // in release mode, assert is compiled out, and b is unused
              // no warning because it is declared [[maybe_unused]]
} // parameters cond1 and cond2 are not used, no warning

int main(void)
{
    f(1, 1);
}

assert(b)는 릴리스 모드에서 컴파일에서 빠지기 때문에 그 때 b는 미사용이 돼요. b[[maybe_unused]]를 붙여두면 이럴 때 경고가 나오지 않아요. 함수 본문에서 쓰이지 않는 매개변수 cond1·cond2도 마찬가지로 속성을 붙여서 경고를 껐어요.

더 알아보기

  • 미사용 경고와 관련된 다른 속성으로 [[deprecated]], [[fallthrough]]가 있어요.
  • C23의 속성 전반은 attributes 문서에서 다뤄요.
  • cppreference의 maybe_unused 원문을 참고할 수 있어요.