c++ - modern - strcpy assert




주장(0)은 무엇을 의미합니까? (3)

내 시험 중 하나에서 이와 같은 질문이 있었는데 아직 답을 구하는 방법이 너무 명확하지 않습니다. 나는 어설 션이 프로그램을 테스트하는 방법이라는 것을 이해하지만 어설 션 assert(0) 이 무엇을 체크하고 있는지 확실하지 않다. 이게 속임수입니까? 그것은 항상 실패 할 것이지만, 나는 왜 그런지 이해하지 못합니다. 무엇을 검사하고 있습니까?

어떤 설명이라도 좋을 것입니다.


C ++ 표준은 assert 의 정의를 C 표준에 의지합니다.

C99 §7.2 / 2 :

" assert 매크로는 진단 테스트를 프로그램에 적용합니다. void 식으로 확장됩니다. 실행될 때 expression (스칼라 유형이어야 함)이 false (즉, 0과 비교) 인 경우 assert 매크로는 실패한 특정 호출에 대한 정보를 기록합니다 (인수의 텍스트, 소스 파일, 소스 라인 번호, 그리고 둘러싼 함수의 이름 - 후자는 표준 오류 파일에있는 구현 정의 형식의 전처리 매크로 __FILE____LINE__ 및 식별자 __func__ 의 값입니다. 그런 다음 abort 함수를 호출합니다.

assert(0) 에서 0false 으로 해석되므로 어설 션 확인이 켜지면이 어설 션은 항상 실패하거나 실행되지 않습니다.

따라서 그것은

"실행은 결코이 시점에 도달하지 않을 것이다."

실제로는 컴파일러가 주어진 지점에 도달하거나 도달하지 못하는 것을 막기가 어려울 수 있습니다. 종종 컴파일러는 값을 반환하지 않고 함수의 끝에 도달 할 가능성이있는 실행에 대해 불평 할 것입니다. assert(0) 추가하면 이상적으로 그 문제를 해결해야하지만, 컴파일러는 assert 에 대해 불평하거나 경고하려고하는 것을 이미 잘 알고 있다고 인식하지 못할 수 있습니다.

하나의 가능한 측정 값은 그 시점에서 예외를 throw하는 것입니다.

auto foo( int x )
    -> int
{
    if( x == 1 ) { return 42; }
    assert( 0 ); throw 0;       // Should never get here!
}

물론 double-whammy는 상위 매크로라고 정의 할 수 있습니다. 예외 유형에 관해서는 std::exception 가 아닌 std::exception 로 유지하고 싶을 수도 있습니다. std::exception 가 아닌 일반적인 catch 의해 catch 되도록 의도 되었기 때문입니다. 또는 표준 예외 계층을 신뢰한다면 (나에게 의미가 없지만) std::logic_error 사용할 수 있습니다.

assertassert 션 검사를 끄려면 <assert.h> 를 포함하기 전에 <assert.h> 심볼을 정의 할 수 있습니다.

이 헤더는 NDEBUG 정의 NDEBUG 여부에 관계없이 여러 번 포함 할 수 있도록 특별한 지원을합니다.

C ++ 11 §17.6.2.2 / 2 :

" 번역 단위는 임의의 순서로 라이브러리 헤더를 포함 할 수 있습니다 (2 절). 각각은 <cassert> 또는 <assert.h> 중 하나를 포함하는 효과가 매번 현재 <assert.h> 의 어휘 적 정의에 의존한다는 것을 제외하고는 정확히 한 번 포함되는 것과는 다른 결과가 나타나지 않고 두 번 이상 포함될 수 있습니다.

위에서 논의한 이중 과자에 대한 합리적인 정의는 마찬가지로 NDEBUG 에 포함 보호 장치가없는 경우도 있습니다 (예 :

assert_should_never_get_here.hpp 파일
#include <stdexcept>        // std::logic_error
#include <assert.h>

#undef ASSERT_SHOULD_NEVER_GET_HERE
#ifdef NDEBUG
#   define ASSERT_SHOULD_NEVER_GET_HERE() \
        throw std::logic_error( "Reached a supposed unreachable point" )
#else
#   define ASSERT_SHOULD_NEVER_GET_HERE() \
        do{ \
            assert( "Reached a supposed unreachable point" && 0 ); \
            throw 0; \
        } while( 0 )
#endif

면책 조항 : 2000 년대 초반에 여러 번 코딩했는데,이 대답을 위의 코드에서 작성했습니다. 그리고 g ++로 테스트했지만 완벽한 것은 아닙니다.

(1) 다른 가능성에 대한 논의는 Basile Starynkevitch의 대답 , g ++ 고유 내장 함수 __builtin_unreachable .


예, 항상 실패합니다.

assert(0) 또는 assert(false) 는 일반적으로 도달 할 수없는 코드 를 표시하는 데 사용되므로 디버그 모드에서 진단 메시지가 표시되고 실제로 도달 할 수 없을 때 프로그램이 중단됩니다. 이는 프로그램이 ' 우리가 생각하는 것을하는 것.


항상 실패합니다. 그것은 거의 그것입니다. x = 5 때마다 "assert (x == 5)"가 성공한다는 동일한 이유로 항상 실패합니다.

응용 프로그램 을 요구하는 경우 실제로는 발생하지 않아야하는 코드 블록에 넣을 수 있습니다.

switch(suit) {
  case CLUB:
  case DIAMOND:
  case HEART:
  case SPADE:
  // ...
  default:
    assert(0);
 }




assertion