Namespaces
Variants

assert

From cppreference.net
헤더 파일에 정의됨 <cassert>
비활성화된 어서션
(1)
#define assert(condition) ((void)0)
(C++26 이전)
#define assert(...)       ((void)0)
(C++26 이후)
활성화된 어서션
(2)
#define assert(condition) /* unspecified */
(C++26 이전)
#define assert(...)       /* unspecified */
(C++26 이후)

매크로 assert 의 정의는 표준 라이브러리에서 정의하지 않는 또 다른 매크로인 NDEBUG 에 따라 달라집니다.

1) 소스 코드에서 <cassert> 또는 <assert.h> 가 포함되는 지점에서 NDEBUG 가 매크로 이름으로 정의된 경우, 어서션은 비활성화됩니다: assert 는 아무 작업도 수행하지 않습니다.
2) 그렇지 않으면, 어서션이 활성화됩니다:

assert 는 인자(스칼라 타입을 가져야 함)를 검사합니다:

  • 인자가 0과 비교하여 같지 않으면, 추가 효과가 없습니다.
  • 그렇지 않으면, assert 는 표준 오류 스트림에 진단 정보를 생성하고 std::abort() 를 호출합니다.
(C++26 이전)

assert 는 프로그램에 진단 테스트를 추가하며 void 타입의 표현식으로 확장됩니다. __VA_ARGS__ 가 평가되고 문맥적으로 bool 로 변환됩니다 :

  • 평가 결과가 true 이면, 추가 효과가 없습니다.
  • 그렇지 않으면, assert 는 표준 오류 스트림에 진단 정보를 생성하고 std::abort() 를 호출합니다.
(C++26 이후)

진단 정보는 구현에 정의된 형식을 가지지만, 항상 다음 정보를 포함합니다:

  • condition의 텍스트 condition
(C++26 이전)
  • #__VA_ARGS__
(C++26 이후)

assert ( E ) 표현식은 다음 중 하나에 해당하는 경우 상수 부분식 이 됨이 보장됩니다:

  • NDEBUG assert 가 마지막으로 정의되거나 재정의된 지점에서 정의된 경우, 또는
  • E bool로 문맥적 변환 bool 되었을 때 true 로 평가되는 상수 부분식인 경우.
(C++11부터)

목차

매개변수

조건 - 스칼라 타입의 표현식

참고 사항

assert 함수형 매크로 이기 때문에, 인자 내에서 괄호로 보호되지 않은 쉼표는 모두 매크로 인자 구분자로 해석됩니다. 이러한 쉼표는 주로 템플릿 인자 목록과 목록 초기화에서 발견됩니다:

assert(std::is_same_v<int, int>);        // error: assert does not take two arguments
assert((std::is_same_v<int, int>));      // OK: one argument
static_assert(std::is_same_v<int, int>); // OK: not a macro
std::complex<double> c;
assert(c == std::complex<double>{0, 0});   // error
assert((c == std::complex<double>{0, 0})); // OK
(C++26 이전)

assert 오류에 추가 메시지를 넣는 표준화된 인터페이스는 존재하지 않습니다. 이식 가능한 방법으로는 콤마 연산자 오버로드 되지 않은 경우 이를 사용하거나, 문자열 리터럴과 함께 && 를 사용하는 방법이 있습니다:

assert(("빛은 다섯 개 있습니다", 2 + 2 == 5));
assert(2 + 2 == 5 && "빛은 다섯 개 있습니다");

assert Microsoft CRT 구현은 C++11 및 이후 개정판을 준수하지 않습니다. 왜냐하면 해당 기본 함수( _wassert )가 __func__ 또는 이에 상응하는 대체자를 전혀 받지 않기 때문입니다.

C++20부터, 진단 메시지에 필요한 값들은 std::source_location::current() 에서도 얻을 수 있습니다.

C23/C++26에서 assert 의 변경이 공식적으로 결함 보고서는 아니지만, C 위원회는 구현체들이 이 변경 사항을 이전 모드로 백포트할 것을 권장합니다.

예제

#include <iostream>
// uncomment to disable assert()
// #define NDEBUG
#include <cassert>
// Use (void) to silence unused warnings.
#define assertm(exp, msg) assert((void(msg), exp))
int main()
{
    assert(2 + 2 == 4);
    std::cout << "Checkpoint #1\n";
    assert((void("void helps to avoid 'unused value' warning"), 2 * 2 == 4));
    std::cout << "Checkpoint #2\n";
    assert((010 + 010 == 16) && "Yet another way to add an assert message");
    std::cout << "Checkpoint #3\n";
    assertm((2 + 2) % 3 == 1, "Success");
    std::cout << "Checkpoint #4\n";
    assertm(2 + 2 == 5, "Failed"); // assertion fails
    std::cout << "Execution continues past the last assert\n"; // No output
}

가능한 출력:

Checkpoint #1
Checkpoint #2
Checkpoint #3
Checkpoint #4
main.cpp:23: int main(): Assertion `((void)"Failed", 2 + 2 == 5)' failed.
Aborted

결함 보고서

다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.

DR 적용 대상 게시된 동작 올바른 동작
LWG 2234 C++11 assert 상수 표현식에서 사용할 수 없었음 사용 가능

참고 항목

contract_assert statement (C++26) 실행 중 내부 조건을 검증합니다
static_assert declaration (C++11) 컴파일 타임 어서션 검사를 수행합니다
비정상적인 프로그램 종료를 유발합니다 (정리 작업 없이)
(함수)