博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ASSERT
阅读量:5834 次
发布时间:2019-06-18

本文共 2505 字,大约阅读时间需要 8 分钟。

参考

http://cnicholson.net/2009/02/stupid-c-tricks-adventures-in-assert/

 

1

#define POW2_ASSERT(x) \ 

    if (!x) { pow2::Assert::Fail(#x, __FILE__, __LINE__); } 

这是最一开始的样子

 

那么POW2_ASSERT(true || false); 

就会变成

if (!true || false) { pow2::Assert::Fail(...); } 

 

2

所以加括号:

#define POW2_ASSERT(x) \ 

    if (!(x)) { pow2::Assert::Fail(#x, __FILE__, __LINE__); } 

 

那么

if (x == 3) 

    POW2_ASSERT(y == 4); 

else 

    DoSomethingReallyImportant(); 

就会变成

if (x == 3) 

    if (!(y == 4)) 

        pow2::Assert::Fail(...); 

    else 

        DoSomethingReallyImportant(); 

破坏了if else

 

3

所以把宏定义用do { … } while(0)包起来

 

于是就变成了:

#define POW2_ASSERT(x) \ 

    do { if (!(x)) { pow2::Assert::Fail(#x, __FILE__, __LINE__); } } while(0) 

 

如果要写成带有宏开关,设定是否要开启assert的情况:

#ifdef POW2_ASSERTS_ENABLED 

    #define POW2_ASSERT(x) \ 

        do { if (!(x)) { pow2::Assert::Fail(#x, __FILE__, __LINE__); } } while(0) 

#else 

    #define POW2_ASSERT(x) 

#endif 

我们设置为不开启

然后像这样调用

const bool success = DoStuff();  POW2_ASSERT(success); 

某些环境下会产生warning:

main.cpp(7) : warning C4189: 'success' : local variable is initialized but not referenced

 

 

4 所以我们把它转换成void

#define POW2_ASSERT(x) do { (void)(x); } while(0) 

 

那么如果

int main(int, char*[]) 

    bool DoStuff(); // comes from another .cpp file 

    POW2_ASSERT(DoStuff()); 

    return 0; 

编译器不知道DoStuff是什么,gcc下它会被调用

虽然warning被消除了但是有副作用

那么怎么能保证不执行DoStuff呢?

我们给它加一个 sizeof

 

5 于是

#ifdef POW2_ASSERTS_ENABLED 

    #define POW2_ASSERT(x) \ 

        do { if (!(x)) { pow2::Assert::Fail(#x, __FILE__, __LINE__); } } while(0) 

#else 

    #define POW2_ASSERT(x) \ 

        do { (void)sizeof(x); } while(0) 

#endif 

 

 

6 有的时候我们希望assert了之后还可以continue

就需要我们自己定义handler来替换__debugbreak() 

dt里面的写法:

 

/// An assertion failure function.

//  @param[in]      expression  asserted expression.

//  @param[in]      file  Filename of the failed assertion.

//  @param[in]      line  Line number of the failed assertion.

///  @see dtAssertFailSetCustom

typedef void (dtAssertFailFunc)(const char* expression, const char* file, int line);

 

/// Sets the base custom assertion failure function to be used by Detour.

///  @param[in]     assertFailFunc  The function to be invoked in case of failure of #dtAssert

void dtAssertFailSetCustom(dtAssertFailFunc *assertFailFunc);

 

/// Gets the base custom assertion failure function to be used by Detour.

dtAssertFailFunc* dtAssertFailGetCustom();

 

#   include <assert.h>

#   define dtAssert(expression) \

        { \

            dtAssertFailFunc* failFunc = dtAssertFailGetCustom(); \

            if(failFunc == NULL) { assert(expression); } \

            else if(!(expression)) { (*failFunc)(#expression, __FILE__, __LINE__); } \

        }

 

#endif

转载于:https://www.cnblogs.com/icebergliu/p/8872261.html

你可能感兴趣的文章
CollabNet_Subversion小结
查看>>
mysql定时备份自动上传
查看>>
17岁时少年决定把海洋洗干净,现在21岁的他做到了
查看>>
linux 启动oracle
查看>>
《写给大忙人看的java se 8》笔记
查看>>
倒计时:计算时间差
查看>>
Linux/windows P2V VMWare ESXi
查看>>
Windows XP倒计时到底意味着什么?
查看>>
运维工程师在干什么学些什么?【致菜鸟】
查看>>
Linux中iptables详解
查看>>
java中回调函数以及关于包装类的Demo
查看>>
maven异常:missing artifact jdk.tools:jar:1.6
查看>>
终端安全求生指南(五)-——日志管理
查看>>
Nginx 使用 openssl 的自签名证书
查看>>
创业维艰、守成不易
查看>>
PHP环境安装套件:快速安装LAMP环境
查看>>
CSS3
查看>>
ul下的li浮动,如何是ul有li的高度
查看>>
C++ primer plus
查看>>
python mysqlDB
查看>>