// 수정1.
// ASSERT 매크로가 조건검사를 하지 않아 수정합니다. 이런 실수를 -ㅡㅡ; 지송...
// 또 기존 assert를 ASSERT 로 변경하는 매크로도 추가합니다.
// 소스가 있으니 입맛에 맞게 변경해 사용하셔도 됩니다.
//---------------------------------------------------------------------------
빌더에는 디버깅을 위해 필요한 조건을 충족하지 못할 경우
그 조건의 내용을 화면에 표시한 뒤
중간에 프로그램을 강제로 종료하는 assert 매크로가 준비되어 있습니다.
VC++에서는 ASSERT 를 사용하는데 비해 빌더는
#include <assert.h>를 한 뒤
assert(조건);
식으로 사용합니다.
assert는 조건이 참인 경우는 그대로 다음 줄로 진행하고 참이 아닌 경우는 그 조건식을 화면에 표시하면서
프로그램이 중단된다는 것은 다 아시죠, ^^;;
그런데, 프로그램하다보면 assert가 별로 마음에 들지 않을때가 있습니다.
사용자 맘에 드는 assert를 구성하고 싶을 때가 있을 수 있으며,
아무리 디버깅 도중 조건테스트에서 중간에 프로그램을 종료한다 하더라도
무언가 불시 종료전에 해주고 싶은 동작이 있을 수 있습니다.
그래서 사용자용 ASSERT를 만들어 올립니다.
소스를 플젝에 포함한뒤
ASSERT(조건);
식으로 사용하면 됩니다.
아래 스샷은 예입니다.
필요하다면 중단 소스를 바꿀 수 도 있습니다.
아마 assert의 동작보다 보기 좋고 중간에 중단되는 것에 대해
사용자 코드를 부가할 수 있으므로 덜 불안할 것입니다.
릴리즈모드에서나 ASSERT_OFF 를 선언한다면
ASSERT 관련 코드는 바이너리 이진코드에서는 완전히 제거됩니다.
이렇게 된다면 ASSERT 동작이 사라지므로 프로그램의 에러를 완전히 잡고난 뒤 릴리즈해야 겠죠.
물론 ASSERT 코드를 포함해서 릴리즈해도 무방합니다.
사용자가 에러난 경우 에러메시지를 쉽게 통보할 수 있어 에러를 쉽게 파악할 수 있으므로,
상용 프로그램에 ASSERT 코드를 그대로 두고 릴리즈하는 경우도 있습니다.
아뭏던 소스가 있으니 적당히 고쳐서 사용할 수 있다는데 큰 의미가 있습니다.
소스를 첨부했지만 간단하므로 여기에 한번 더 나열하겠습니다.
ASSERT.h
//---------------------------------------------------------------------------
// 사용자 ASSERT
// Written by 김태성 jsdkts@korea.com
//---------------------------------------------------------------------------
#ifndef ASSERTH
#define ASSERTH
#define xASSERT_OFF
#if (defined(ASSERT_OFF) || !defined(_DEBUG))
// 릴리즈모드에서는 ASSERT을 모두 제거하기 위함이다.
#define ASEERT 1 ? (void) 0 : ___DeleteASSERT
inline void ___DeleteASSERT(const char *str, ...)
{
// empty code.
}
#else
#define ASSERT(p) if (!(p)) ASSERT_FUNC(#p, __FILE__, __FUNC__, __LINE__)
void ASSERT_FUNC(char *condition, char *file, char *func, int line);
/*
// 헤더 하나로만 사용하고 싶은 경우 inline으로 선언된 아래 함수를 사용하면 됩니다.
inline void ASSERT_FUNC(char *condition, char *file, char *func, int line)
{
char szBuffer[4097];
wsprintf(szBuffer, "%s\n\n소스파일: %s 라인 %d\n함수명 : %s\n",
condition, file, line, func);
MessageBox(NULL, szBuffer, "ASSERT", MB_OK | MB_ICONWARNING);
Application->Terminate();
throw Exception("ASSERT 종료: Application terminate");
}
*/
#endif
#endif
ASSERT.cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "ASSERT.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
static void ASSERT_FUNC(char *condition, char *file, char *func, int line)
{
char szBuffer[4097];
wsprintf(szBuffer, "%s\n\n소스파일: %s 라인 %d\n함수명 : %s\n",
condition, file, line, func);
MessageBox(NULL, szBuffer, "ASSERT", MB_OK | MB_ICONWARNING);
// 이런식의 종료를 해도 좋고, 사용자가 코드를 추가하거나 바꾸어도 좋습니다.
Application->Terminate();
throw Exception("ASSERT 종료: Application terminate");
}
사용은
void __fastcall TForm1::Button1Click(TObject *Sender)
{
int k = 1;
ASSERT(k == 2); // 여기 ASSERT 조건
int kk = k;
Caption = kk;
MessageBox(NULL, "test", "ttt", MB_OK);
}
식으로 한다면 ASSERT 구문의 조건이 false가 되므로
해당 줄의 조건과 소스파일명, 함수명, 라인번호를 표시한뒤 프로그램은 중단되게 됩니다.
즉 위에서 ASSERT 다음 줄은 전혀 실행이 안되게 되죠.
ASSERT_FUNC 함수 소스에서 중단코드를 살펴보면 메시지를 표시한뒤
어플 종료 함수를 부르고 난 뒤 예외를 발생시켜 순리적으로 종료시킵니다.
화면 모습은 아래와 같습니다.
그럼.