Static assert는 표현식(조건)이 충족되지 않을 경우 컴파일 타임에 오류를 생성하는 컴파일러 메커니즘입니다. 이 기능은 C++11부터 추가되어 템플릿 프로그래밍을 용이하게 하고 코드 품질을 높이는 데 도움을 줍니다.
배경.
static_assert가 등장하기 전, 프로그래머들은 배열의 크기가 음수인 구조체와 같은 트릭을 사용했습니다(예: char arr[condition?1:-1];), 이는 읽기가 힘들고 오류 진단에 불편했습니다. 이로 인해 의미 있는 컴파일 타임 오류 메시지를 명시적으로 선언하는 필요성이 생겼습니다.
문제.
템플릿 프로그래밍에서는 종종 이른 진단이 필요합니다(예: 부적합한 타입이나 매개변수를 가진 객체 생성 금지). 정적 검사가 없으면 이러한 오류는 최종 코드 컴파일 단계에서만 발생하였고(때로는 갑작스럽고 설명하기 어려운 오류), 이는 문제를 증가시켰습니다.
해결책.
static_assert 키워드는 불린 표현식과 메시지 문자열을 받습니다. 표현식이 거짓일 경우 컴파일은 오류 메시지와 함께 종료됩니다.
코드 예시:
static_assert(sizeof(int) >= 4, "int는 최소 4바이트여야 합니다"); template<typename T> void foo(const T& obj) { static_assert(std::is_copy_constructible<T>::value, "T는 복사 가능해야 합니다"); }
주요 특징:
두 번째 인수 없이 static_assert를 사용할 수 있나요?
네, C++17부터 두 번째 인수는 선택적입니다:
static_assert(sizeof(double) == 8); // 메시지는 기본값이 됩니다
조건이 템플릿 매개변수에 의존하는 경우 static_assert 표현식이 실행되나요? 하지만 템플릿이 인스턴스화되지 않았습니다.
아니요, static_assert는 인스턴스화 지점에 도달해야만 작동하여 사용되는 템플릿에 대해서만 검사가 가능합니다.
static_assert 내부에 런타임 표현식을 사용할 수 있나요?
아니요, 표현식은 컴파일 타임에 계산 가능해야 합니다(상수 표현식). 표현식이 constexpr가 아니면 컴파일 오류가 발생합니다.
코드에서 static_assert를 런타임에만 계산되는 표현식과 함께 사용했으며(예: 입력 읽기로 파일 크기), 이는 시스템 전체에서 이해할 수 없는 컴파일 오류를 유발했습니다.
장점:
단점:
템플릿 Matrix가 오직 Plain Old Data (POD) 타입으로만 생성될 수 있도록 보장해야 합니다, 복잡한 구조는 제외됩니다.
template<typename T> class Matrix { static_assert(std::is_pod<T>::value, "Matrix는 POD 타입에 대해서만 인스턴스화될 수 있습니다"); // ... };
장점:
단점: