自定义系统中使用的Assert工具,类似Q_ASSERT的简化版
概要
书接上回,项目开始定义了一些系统的平台参数,具体可参见下面的文章:C++ 项目成长 —— 定义跨平台的参数宏的文件记录。
同时,在上次我们尝试去定义了一些编译选项自定义的宏,来控制不同的编译选项的时候,能够做一些区分,具体可以参考下面的文章:C++ 项目成长 —— 自定义编译参数宏,区分编译选项
上回说到一下关于自定义一些自己项目中所用到的数据类型,那么可以参考上次的文章:
C++ 项目成长 ——自定义数据类型,定义各种类型别名, typedef的部分用法实例
这次呢,我们定义了一些类型之后,有时候会在项目中,需要去动态调试一些情况,判断是否存在空指针,最终得到的某些结果是否是我们期望的判断条件等,那么就需要用一个运行时的Assert来告诉我们,可能项目出错,中断在了什么地方,哪里是有问题的,方便我们在以后写代码的过程中,能够更快的去定位到问题,这种情况尤其更适用于寻找内存出错的问题。那么,我就把自己写的一个简陋的Assert给分享出来吧。
TZOpenTools
tzsofts_assert.h
///
// Copyright (c)2021, Tom Zhao personal. ("TZOpenTools")
// This software is a personal tools project by Tom Zhao.
// Description:
///
#ifndef _TZSOFTS_ASSERT_H_H
#define _TZSOFTS_ASSERT_H_H
#include "zsofts_types.h"
#include "platform_export.h"
#ifdef TZ_WINDOWS
#include <crtdbg.h>
#else
#include <stdio.h>
#include <wchar.h>
#endif // TZ_WINDOWS
#include <assert.h>
#pragma pack(push, 8)
TZ_NAMESPACE_BEGIN(TzSoft)
typedef void(*TzAssertFunc) (const TZTCHAR* expression, const TZTCHAR* fileName, int lineNumber);
class TZ_PLATFORM_STATIC_EXPORT Asserter
{
public:
Asserter(const TZTCHAR* expression, const TZTCHAR* fileName, int lineNumber)
{
// (*sm_pfnAssert)(expression, fileName, lineNumber);
defaultAssert(expression, fileName, lineNumber);
}
~Asserter()
{
}
static TzAssertFunc setAssertFunction(TzAssertFunc pfnAssert)
{
TzAssertFunc pfnOldFunc = sm_pfnAssert;
sm_pfnAssert = pfnAssert;
return pfnOldFunc;
}
private:
static void defaultAssert(const TZTCHAR* expression, const TZTCHAR* fileName, int lineNumber)
{
#if TZ_BUILD_MODE == TZ_BUILD_DEBUG && TZ_COMPILER == TZ_COMPILER_MSVC && TZ_PLATFORM != TZ_PLATFORM_WINCE
# if TZ_COMPILER_VER >= TZ_COMPILER_MSVC_8_0
if (1 == _CrtDbgReportW(_CRT_ASSERT, fileName, lineNumber, NULL, expression))
_CrtDbgBreak();
# elif TZ_COMPILER_VER >= TZ_COMPILER_MSVC_7_0
_assert(expression, fileName, lineNumber);
# else
_assert((void *)expression, (void *)fileName, lineNumber);
# endif
#endif // TZ_BUILD_MODE == TZ_BUILD_DEBUG && TZ_COMPILER == TZ_COMPILER_MSVC && TZ_PLATFORM != TZ_PLATFORM_WINCE
}
TZ_PLATFORM_EXPORT_STATIC static TzAssertFunc sm_pfnAssert;
};
TZ_NAMESPACE_END(TzSoft)
#endif // !_TZSOFT_ASSERT_H_H
tzsofts_assert.cpp
///
// Copyright (c)2020, Tom Zhao personal. ("TZOpenTools")
// This software is a personal tools project by Tom Zhao.
// Description:
///
#include "pch.h"
#include "tzsofts_assert.h"
TZ_NAMESPACE_BEGIN(TzSoft)
#if defined(TZ_WINDOWS)
#if defined(TZ_USE_DEBUGOUTPUT_FOR_ASSERTION_FAIL)
void debugOutputAssert(const TZTCHAR* expression, const TZTCHAR* fileName, int lineNumber)
{
static const TZCHAR* _s_debug_assertion_fmt = TZ_T("\nASSERT FAIL!!!!\nExpression:\"%s\"\nOccur at:\"%s(line %d)\"\n");
const size_t _debug_assertion_fmt_strlen = tz_strlen(_s_debug_assertion_fmt) +
(NULL == expression ? 1 : tz_strlen(expression)) +
(NULL == fileName ? 1 : tz_strlen(fileName)) + 20;
TZCHAR * _assertInfoForStr = new TZCHAR[_debug_assertion_fmt_strlen];
if (tz_stprintf(_assertInfoForStr, _s_debug_assertion_fmt, expression, fileName, lineNumber) > 0)
{
::OutputDebugString(_assertInfoForStr);
}
delete[] _assertInfoForStr;
}
TZ_PLATFORM_STATIC_EXPORT TzAssertFunc Asserter::sm_pfnAssert = debugOutputAssert;
#else
TZ_PLATFORM_STATIC_EXPORT TzAssertFunc Asserter::sm_pfnAssert = Asserter::defaultAssert;
#endif
#else
// TODO: Put assert method for platform that other than windows.
static void otherAssert(const TZCHAR* expression, const TZCHAR* fileName, int lineNumber)
{
wprintf(TZ_T("\nTzAsserter failed -- %ls:%d "), fileName, lineNumber);
}
TZ_PLATFORM_STATIC_EXPORT TzAssertFunc Asserter::sm_pfnAssert = otherAssert;
#endif
TZ_NAMESPACE_END(TzSoft)
个人格言
用心去感受你自己需要坚持的生活,未来慢慢会给你答案的。