정적 단언(Static assertion, C11부터)

정적 단언(Static assertion, C11부터)

컴파일 타임에 어떤 조건이 참인지 확인하고 싶을 때 쓰는 게 정적 단언이에요. 런타임에 프로그램을 잡는 게 아니라, 빌드 자체를 실패시켜야 할 조건을 선언으로 만들 수 있어요.

출처: cppreference

본문

문법

_Static_assert ( expression , message ) (C11부터)(C23에서 deprecated)
static_assert ( expression , message ) (C23부터)
_Static_assert ( expression ) (C23부터)(C23에서 deprecated)
static_assert ( expression ) (C23부터)
항목 의미
expression - 임의의 정수 상수 표현식
message - 임의의 문자열 리터럴

이 키워드는 편의 매크로 static_assert로도 쓸 수 있고, 이 매크로는 <assert.h> 헤더에서 쓸 수 있었어요. (C23 이전)

static_assert_Static_assert 둘 다 효과는 같아요. _Static_assert는 호환성을 위해 남겨둔, deprecated된 표기예요. (C23부터)

구현이 static_assert 및/또는 _Static_assert를 미리 정의된 매크로로 정의할 수도 있고, C23부터는 static_assert가 더 이상 <assert.h>에서 제공되지 않아요.

설명(Explanation)

상수 표현식은 컴파일 타임에 평가되어 0과 비교돼요. 0과 같으면 컴파일 타임 오류가 발생하고, 컴파일러는 오류 메시지의 일부로 message를 표시해야 해요(기본 문자 집합에 없는 문자는 표시하지 않아도 됨, C23 이전)(제공된 경우 message를 오류 메시지의 일부로 표시해야 함, C23부터).

반대로 expression이 0이 아니면 아무 일도 일어나지 않아요. 코드도 생성되지 않아요.

키워드(Keywords)

_Static_assert, static_assert

예제(Example)

#include <assert.h> // no longer needed since C23

int main(void)
{
    // Test if math works, C23:
    static_assert((2 + 2) % 3 == 1, "Whoa dude, you knew!");
    // Pre-C23 alternative:
    _Static_assert(2 + 2 * 2 == 6, "Lucky guess!?");

    // This will produce an error at compile time.
    // static_assert(sizeof(int) < sizeof(char), "Unmet condition!");

    constexpr int _42 = 2 * 3 * 2 * 3 + 2 * 3;
    static_assert(_42 == 42); // the message string can be omitted.

    // const int _13 = 13;
    // Compile time error - not an integer constant expression:
    // static_assert(_13 == 13);
}

코드에서 보이는 대로, 조건이 성립하면 아무 일도 없고 조건이 깨지면 컴파일이 실패해요. 또 C23부터는 메시지 문자열을 생략할 수 있어요. 그리고 const int 값은 정수 상수 표현식이 아니라서 static_assert의 피연산자로 쓸 수 없는 점도 눈여겨볼게요.

더 알아보기

  • assert: 프로그램이 조건이 거짓이면 중단하는 런타임 매크로(릴리스 빌드에서 끌 수 있어요).
  • constexpr(C23): 컴파일 타임 상수를 선언하는 지정자.