블로그 이미지
자신의 단점을 메꾸는 것을 단(鍛)이라 하고 자신의 강점을 갈고 닦는 것을 련(鍊)이라 하여, 두가지를 합친 것을 단련이라고 부른다. 붕대마음

카테고리

전체목록 (666)
참고사이트 (8)
Goal (4)
Travel (10)
My Life (105)
Game (35)
Game Review (7)
Game Plan (0)
Books (5)
English (1)
Optimizing (12)
Study (217)
유용한 것들_etc (44)
유용한 것들_func (20)
Unity (48)
Unreal (87)
작업장 (54)
RenderMonkey (6)
정리요망 (1)
따라잡기 시리즈 (0)
링크용 (0)
Total343,844
Today11
Yesterday82

'ct_assert'에 해당되는 글 2건

  1. 2014.09.21 2. Core - Assert.
  2. 2010.06.10 compile time assertion

assert 기능은 프로젝트 진행에 무척 자주 사용하는 기능이다.
그냥 단순히 log 기능이라고 해도 무방할 듯 하다.
assert 기능의 구현은 크게 runtime과 compiletime으로 나뉘며
적당히 사용하면 되는데 매번 바뀌는 변수는 runtime으로 매번 체크를 하고
한번 체크후 절대 바뀌지 않는것은 compiletime으로 체크해서
매번 비교하는 부하를 없애주는데 의의가 있다.

이 작업을 하면서 살짝 삽질했던 dll 링크 관련 문제는 아래 링크를 참조하면 된다.

기존 버전 작업에는 이 assert가 core 외부에 별도의 프로젝트로 했었는데 
이번에 수정하면서 core쪽에 추가해 버렸다. 너무 세세하게 프로젝트를 나누다 보니
프로젝트가 너무 많아지고 그에따라 dll도 많아지고...그냥 그렇다.

소스는 간단하게 핵심 부분만 적어둔다.

1. dll import, export 관련.
#ifdef MGASSERT_EXP_DLL
#define MGASSERT_DLLDECL __declspec(dllexport)
#elif defined MGASSERT_IMP_DLL
#define MGASSERT_DLLDECL __declspec(dllimport)
#else
#define MGASSERT_DLLDECL 
#endif

2. unicode 관련.
namespace std
{
#if defined UNICODE || defined _UNICODE
typedef wstring tstring;
typedef wstringstream tstringstream;
#else
typedef string tstring;
typedef stringstream tstringstream;
#endif
}

3. assert 정의.
template<bool> struct CTAssert;
template<> struct CTAssert<true> {};
#define CT_ASSERT( exp) \
{ \
CTAssert<exp> _COMPILE_TIME_ASSERT_\
CTAssert<exp>* __p_ctassert_instance = &_COMPILE_TIME_ASSERT_; \

위의 CTAssert 템플릿을 보면 자료형이 아닌 bool 상수를 인자로 취하고 있따.
게다가 오직 bool 값이 true일 경우에만 정의되어 있다.
그렇다면 이 템플릿을 인스턴스화 할 때 true값 이외의 값을 넘겨주려 하면
템플릿이 정의되어 있지 않아 컴파일러가 에러를 발생시킨다는 것을 이용한다. 

이외에도 RT assert도 설정 할 수 있다.

그리고 윈도우 프로젝트라면 리소스 파일을 이용해서 dialog를 이용할 수도 있을 것이다.


DialogBox(instance, MAKEINTRESOURCE(다이얼로그 아이디), wnd, AssertDlgProc);

Mgin, ConsoleTester, main.cpp, TestAssert()


Reference Links
- c/c++에서 Compile Time Assertion
http://mtorange.blog.me/120019424125
compile time assertion
- Windows 동적 라이브러리(DLL)만들기 & 사용하기
- pre compile header. 미리 컴파일 헤더
- Unicode 사용하기
- gpg assert 논의


'작업장 > Mgin 제작' 카테고리의 다른 글

5. 프로젝트 설정 - dll  (0) 2014.10.09
3. dx 라이브러리 설정.  (0) 2014.09.22
2. Core - Assert.  (0) 2014.09.21
1. Property Sheet  (0) 2014.09.20
model tool - Lighting.  (0) 2012.01.07
DXUT BackBuffer assert  (0) 2011.07.06
Posted by 붕대마음

댓글을 달아 주세요

compile time assertion

Study/C++ / 2010.06.10 22:20

중요한 안건은 두가지.
runtime assert를 compile time assert로 대체.
이를 대체하면서 적절한 에러메세지 출력.

안전한 형변환을 위해 아래와 같이 만들었다고 생각해보자.
#include <assert.h>

// 안전한 형변환을 위해 선언.
template <class To, class From>
To safe_reinterpret_cast(From from)
{
 assert(sizeof(from) <= sizeof(To));
 return reinterpret_cast<To>(from);
}

int _tmain(int argc, _TCHAR* argv[])
{
 int i   = 4;
 char* p = safe_reinterpret_cast<char*>(i);
 return 0;
}

즉, To에 쓰인 자료형이 From에 쓰인 자료형의 모든 비트데이터를 수용할 수 있는 크기인지가 관건이다.
그렇지 않다면 assert(런타임 어설트)가 발생한다.

만일, 이러한 에러를 컴파일 타임에 잡아낼 수 있을까?
관심있게 봐야 할 부분은 assert() 함수 이다.
이 구문에서 인자로 사용되고 있는 비교식은 컴파일러 입장에서 볼 때 상수로 분류된다.
즉, 컴파일러에게 0이 아닐 경우에는 적법하고, 0일 경우에는 문제가 되는 구문을 언어적 구조로 표현하여
넘겨주면 되지 않을까?..

0일 경우에 문제가 되는 구문중 하나가 길이가 0인 배열이다.
c와 c++에서는 길이가 0인 배열을 허용하지 않는다는 것에 주목하자.
아래와 같이 매크로를 살짝 만들어 줄 수 있다.
#define  STATIC_CHECK(expr) {char unnamed[(expr)?1:0];}

이제 컴파일 타임 어설트도 만들었으니 런타임 어설트를 대신하여 사용해 보자.

template <class To, class From>
To safe_reinterpret_cast(From from)
{
 STATIC_CHECK(sizeof(from) <= sizeof(To));
 return reinterpret_cast<To>(from);
}

int _tmain(int argc, _TCHAR* argv[])
{
 int i   = 4;
 void* point = &i;
 char p = safe_reinterpret_cast<char, void*>(point);
 return 0;
}

이를 컴파일 하면 "error C2466: 상수 크기 0의 배열을 할당할 수 없습니다."와 같은 문구가 뜨면서 컴파일시 에러가 뜬다.

이제 에러메세지에 특별한 의미를 부여해야 한다.
컴파일러는 에러메세지에서 템플릿의 이름을 언급해 줄 수 있다.
template<bool> struct CompileTimeError;
template<> struct CompileTimeError<true> {};
#define  STATIC_CHECK2(expr) (CompileTimeError<(expr) != 0>())

위와같이 bool상수를 인자로 하고, bool값이 true인 경우에 대해서만 정의하므로
false에 대한 템플릿의 특화는 정의돼어 있지 않다는 에러메세지를 받을 수 있다.
이 에러메세지는 프로그래머가 의도한 에러메세지임을 알아야 한다.

template<int> struct CompileTimeError;
template<> struct CompileTimeError<true> {};

#define STATIC_CHECK(expr, msg) \
{ CompileTimeError<((expr) != 0)> ERROR_##msg; (void)ERROR_##msg; }


// 안전한 형변환을 위해 선언.
template <class To, class From>
To safe_reinterpret_cast(From from)
{
 STATIC_CHECK(sizeof(from) <= sizeof(To), Destination_Type_Too_Narrow)
 return reinterpret_cast<To>(from);
}

define static_check가 false를 얻으면 컴파일 타임에서 에러가 나고 에러메세지는
정의한 메크로에 의해 아래와 같은 형식으로 출력이 된다.

'ERROR_Destination_Type_Too_Narrow'은(는) 정의되지 않은 struct 'CompileTimeError<__formal>'을(를) 사용합니다.
위의 메세지를 통해 디버깅을 좀 더 빨리 편하게 할 수 있다.

'Study > C++' 카테고리의 다른 글

warning C4251  (0) 2010.06.26
참조카운팅 + 스마트포인터 템플릿  (0) 2010.06.16
compile time assertion  (0) 2010.06.10
FileChecker  (0) 2010.06.09
STL의 std::string::find_last_of 사용 시 주의 사항  (0) 2010.06.04
__int8, __int16, __int32, __int64  (0) 2010.05.30
Posted by 붕대마음

댓글을 달아 주세요

최근에 달린 댓글

최근에 받은 트랙백

글 보관함