문제

즉, 내 코드에 유용한 주장을하기 위해 무엇을해야합니까?

MFC는 매우 쉽습니다. 나는 단지 Assert (무언가)를 사용합니다.

MFC가 아닌 방법은 무엇입니까?

편집하다: assert ()라는 내 파일보다는 assert.c에서 끊임없는 Assert를 중단 할 수 있습니까?

편집하다: 차이점은 무엇입니까? <assert.h> & <cassert>?

받아 들여진 답변 : 이 게시물에서 많은 훌륭한 답변이 있습니다. 여러 개 이상의 답변을 받아 들일 수 있기를 바랍니다 (또는 누군가가 모두 결합 할 것입니다). 따라서 답변은 Ferruccio (첫 번째 답변)에게 수여됩니다.

도움이 되었습니까?

해결책

#include <cassert>

assert(something);

컴파일 타임 확인을 위해 Boost의 정적 어설 션은 매우 유용합니다.

#include <boost/static_assert.hpp>

BOOST_STATIC_ASSERT(sizeof(int) == 4);  // compile fails if ints aren't 32-bit

다른 팁

그것은 당신이 Visual C ++ 밖에서 작동하는 것을 찾고 있는지 여부에 따라 다릅니다. 또한 원하는 유형의 주장에 따라 다릅니다.

몇 가지 유형의 주장이 있습니다.

  1. 전처리 서
    이러한 주장은 사전 처리기 지침을 사용하여 수행됩니다 #error
    전처리 자제는 전처리 단계에서만 평가되므로 템플릿과 같은 것에 유용하지 않습니다.

  2. 시간을 실행하십시오
    이 주장은 다음을 사용하여 수행됩니다 assert() 정의 된 기능 <cassert>
    실행 시간 어설 션은 런타임에만 평가됩니다. 그리고 볼트 바이트가 지적했듯이 NDEBUG 매크로가 정의되었습니다.

  3. 공전
    이 주장은 당신이 말했듯이, ASSERT() 매크로이지만 MFC를 사용하는 경우에만. C/C ++ 표준의 일부인 정적 주장을 수행하는 또 다른 방법을 모르지만 Boost 라이브러리는 또 다른 솔루션을 제공합니다. static_assert.
    그만큼 static_assert 부스트 라이브러리의 기능은 C ++ 0x 표준.

추가 경고로 assert() Ferruccio가 제안한 기능은 MFC와 동일한 동작을 가지고 있지 않습니다. ASSERT() 매크로. 전자는 실행 시간 주장이며 나중에는 정적 인 주장입니다.

이게 도움이 되길 바란다!

Assert는 (보통) 디버그 전용입니다

"Assert"의 문제점은 일반적으로 디버그 바이너리에 있으며 일부 개발자는 코드가 여전히 제작되는 것처럼 사용한다는 것입니다.

코드가 집중적으로 테스트되어야하므로 이는 악한 자체가 아닙니다. 따라서 어설 션을 생성하는 버그가 반드시 발견되어 제거 될 것입니다.

그러나 때때로 (대부분의 시간?), 테스트는 원하는만큼 집중적이지 않습니다. 나는 마지막 순간까지 코딩해야 할 오래된 직업에 대해 말하지 않을 것입니다 (묻지 마세요 ... 때때로 관리자는 그냥 ... 아 ...) ... 다음 순간에 클라이언트에게 릴리스 바이너리로 컴파일되고 전달 될 코드에 추가하는 주장의 요점은 무엇입니까?

(일부) 실제 응용 프로그램을 주장합니다

우리 팀에서는 오류를 감지 할 무언가가 필요했고 동시에 오류를 처리하기 위해 다른 것을 필요로했습니다. 그리고 우리는 잠재적으로 릴리스 빌드에 그것을 필요로했습니다.

Assert는 디버그 빌드에서만 오류를 감지하고 처리합니다.

대신 XXX_ASSERT 매크로와 XXX_RAISE_ERROR 매크로를 추가했습니다.

XXX_Assert 매크로는 Assert 매크로와 같은 일을하지만 디버그와 릴리스에서 구축 될 것입니다. 동작 (로그 작성, 메시지 상자 열기, 아무것도하지 않는 등)은 .ini 파일로 제어 할 수 있으며 응용 프로그램을 중단/종료 할 수 있습니다.

이것은 다음과 같이 사용되었습니다.

bool doSomething(MyObject * p)
{
   // If p is NULL, then the app will abort/exit
   XXX_ASSERT((p != NULL), "Hey ! p is NULL !") ;

   // etc.
}

xxx_raise_error 매크로는 오류 만 "로그"하지만 처리하려고 시도하지는 않습니다. 즉, 메시지를 파일에 로그인하거나 메시지와 함께 메시지 상자를 열고 버튼을 계속하고 다른 하나는 디버그 세션 (.ini 파일 구성에 따라)을 시작할 수 있습니다. 이것은 다음과 같이 사용되었습니다.

bool doSomething(MyObject * p)
{
   if(p == NULL)
   {
      // First, XXX_RAISE_ERROR will alert the user as configured in the INI file
      // perhaps even offering to open a debug session
      XXX_RAISE_ERROR("Hey ! p is NULL !") ;
      // here, you can handle the error as you wish
      // Than means allocating p, or throwing an exception, or
      // returning false, etc.
      // Whereas the XXX_ASSERT could simply crash.
   }

   // etc.
}

우리의 libs에 소개 된 지 1 년 후, xxx_raise_error 만 사용됩니다. 물론, 그것은 앱의 시간 크리티컬 부분에서 사용할 수 없지만 (우리는 그것을 위해 xxx_raise_error_dbg가 있습니다), 다른 곳에서는 좋습니다. 또한 선호하는 오류 처리를 사용할 수 있고 개발자 컴퓨터, 테스터 또는 사용자에서도 마음대로 활성화 될 수 있다는 사실은 매우 유용합니다.

두 번째 "편집"의 질문에 답하기 위해 :

<assert.h>는 C 헤더입니다

<cassert>는 C ++ 표준 라이브러리 헤더입니다 ... 일반적으로 <assert.h>를 포함합니다.

Assert라고 불리는 파일 내부를 끊으려면 예외 나 호출을 던지는 사용자 정의 매크로를 사용할 수 있습니다. __debugbreak:

#define MYASSERT(EXPR, MSG) if (!(EXPR)) throw MSG;

또는:

#define MYASSERT(EXPR) if (!(EXPR)) __debugbreak();

기본 어제 사용법

#include <cassert>

/* Some code later */
assert( true );

모범 사례 메모

어설 션은 식별하는 데 사용됩니다 런타임 상태는 사실입니다. 결과적으로 릴리스 모드로 컴파일됩니다.

항상 맞지 않기를 원하는 상황이 있다면, 당신은 그것을 거짓으로 전달할 수 있습니다. 예를 들어:

switch ( someVal ):
{
case 0:
case 1:
  break;
default:
  assert( false ); /* should never happen */
}

Assert를 통해 메시지를 전달할 수도 있습니다.

assert( !"This assert will always hit." );

성숙한 코드베이스는 자주 Assert 기능을 확장합니다. 공통 확장 중 일부는 다음과 같습니다.

  • 테스트를 현지화하기 위해 모듈별로 주장합니다.
  • 대부분의 디버그 빌드에서 컴파일되는 추가 Assert 매크로 생성. 이것은 매우 자주 (초당 수백만 번)로 호출되는 코드에 바람직하며 틀리지 않을 것입니다.
  • 사용자가 현재 히트 어설 션을 비활성화 할 수 있도록 허용합니다. 이로 인해 양성 주장이 트리거되는 것을 막아서 사용할 수없는 빌드를 만듭니다.

Microsoft 별 CRT Asserts

#include <crtdbg.h>
#include <sstream>
...
// displays nondescript message box when x <= 42
_ASSERT(x > 42);
// displays message box with "x > 42" message when x <= 42
_ASSERTE(x > 42);
// displays message box with computed message "x is ...!" when x <= 42
_ASSERT_EXPR(
   x > 42, (std::stringstream() << L"x is " << x << L"!").str().c_str());

Modassert라는 고급 오픈 소스 라이브러리가 있으며, 이는 Visual C ++ 및 GCC 모두에 대한 주장이 있습니다. 아마도 다른 컴파일러에서도 확실하지 않습니다. 그것을 배우는 데 약간의 시간이 걸리지 만 MFC에 의존하지 않는 좋은 주장을 원한다면 이것을보십시오. 그것은있다 http://sourceforge.net/projects/modassert/

IntellISENSE를 사용하여 Visual Studio에서 열립니다 (오른쪽 클릭)

// cassert standard header
#include <yvals.h>
#include <assert.h>

yvals.h는 Windows 물건입니다. 따라서 Assert () 자체에 관한 한, 그것을 포함시키는 두 가지 방법은 동일합니다. 사용하는 것이 좋습니다 <cxxx> 종종 그렇게 간단하지 않기 때문에 (네임 스페이스 포장 및 다른 마법)

이것은 나를 위해 발신자 사이트에서 중단됩니다 ...

여기에 있습니다 기사 이 매크로를 직접 쓰고 싶지 않은 이유를 설명합니다.

다음은 C ++에서 가장 최근의 주장 시설 반복입니다. http://pempek.net/articles/2013/11/17/cross-platform-cpp-assertion-library/

프로젝트에 쉽게 추가 할 수있는 드롭 인 2 파일입니다.

Asker의 세 번째 질문에 답하기 위해 : "Assert.h"대신 "Cassert"를 사용하는 첫 번째 이유는 C ++의 경우 C ++ 컴파일러가 코드에 함수 설명을 저장하지 않을 수 있다는 사실에 대한 허용량이 있기 때문입니다. 파일이지만 DLL 또는 컴파일러 자체에 있습니다. 두 번째는 현재 또는 미래에 C와 C ++의 차이를 용이하게하기 위해 기능이 약간 변경 될 수 있다는 것입니다. Assert.h는 C 라이브러리이기 때문에 선호도는 C ++에있는 동안 "Cassert"를 사용하는 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top