前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >断言assert()与调试帮助

断言assert()与调试帮助

作者头像
Enterprise_
发布2019-02-20 14:53:42
5970
发布2019-02-20 14:53:42
举报
文章被收录于专栏:小L的魔法馆小L的魔法馆
  • 列表内容assert()是一种预处理宏(preprocessor marco),使用一个表达式来作为条件,只在DEBUG模式下才有用。
代码语言:javascript
复制
assert(expr);

对expr求值,如果expr为假,则输出信息并终止程序,反之则什么也不做。 用来检查”不会发生”的条件。 assert的行为依赖与NDEBUG的预处理变量的状态,如果定义了这个变量,则assert什么也不做。如果定义了NDEBUG,编译器会认为是非DEBUG模式(like release模式)

代码语言:javascript
复制
#include<iostream>
#include<string>
// 去注释则禁用 assert()
//#define NDEBUG
#include<cassert>
using namespace std;
int main()
{
    string word;
    size_t the = 5;
    cin >> word;
    assert(word.size() > the);

    if (word.size() < the) {
        cerr << "Error :" << __FILE__
            << " : in function " << __func__
            << " at line " << __LINE__ << endl
            << "        Compiled on " << __DATE__
            << " at " << __TIME__ << endl
            << "        Word read was \"" << word
            << "\": Length too short " << endl;
    }

    return 0;
}

未去注释版本在assert(word.size() > the);这里会退出,如下图

这里写图片描述
这里写图片描述

去注释版本,禁用assert(),则继续执行

这里写图片描述
这里写图片描述
  • 这里有一个问题,如果这么写,将宏定义写在<cassert>头文件之后的话,那么这个禁用将不起效果,这里的assert()仍然会执行。
代码语言:javascript
复制
#include<iostream>
#include<string>
#include<cassert>
using namespace std;
#define NDEBUG
using namespace std;
int main()
{
    string word;
    size_t the = 5;
    cin >> word;
    assert(word.size() > the);

    if (word.size() < the) {
        cerr << "Error :" << __FILE__
            << " : in function " << __func__
            << " at line " << __LINE__ << endl
            << "        Compiled on " << __DATE__
            << " at " << __TIME__ << endl
            << "        Word read was \"" << word
            << "\": Length too short " << endl;
    }

    return 0;
}
  • 但是为什么呢?打开#include<cassert>文档看到这个,说明C++仍然采用了C的定义,所以继续打开#include <assert.h>
代码语言:javascript
复制
// cassert standard header
// NOTE: no include guard
#include <yvals.h>
#include <assert.h>
代码语言:javascript
复制
//
// assert.h
//
//      Copyright (c) Microsoft Corporation. All rights reserved.
//
// Defines the assert macro and related functionality.
//
#if defined _VCRT_BUILD && !defined _ASSERT_OK
    #error assert.h not for CRT internal use
#endif

#include <corecrt.h>

_CRT_BEGIN_C_HEADER

#undef assert

#ifdef NDEBUG

    #define assert(expression) ((void)0)

#else

    _ACRTIMP void __cdecl _wassert(
        _In_z_ wchar_t const* _Message,
        _In_z_ wchar_t const* _File,
        _In_   unsigned       _Line
        );

    #define assert(expression) (void)(                                                       \
            (!!(expression)) ||                                                              \
            (_wassert(_CRT_WIDE(#expression), _CRT_WIDE(__FILE__), (unsigned)(__LINE__)), 0) \
        )

#endif

_CRT_END_C_HEADER

所以在这之前定义了NDEBUG,assert(expression)就变成了((void)0),也就是禁用了,否则才会开始执行检查。 而如果在这个之后定义了NDEBUG,也就相当于在上面最后又加了一句#define NDEBUG,但是这个时候检查已经开始了,所以这一句也没用了。

  • 辅助诊断变量,均在预处理器中定义.
代码语言:javascript
复制
__FILE__    //存放文件名的字符串字面值
__LINE__    //存放当前行号的整型字面值
__TIME__    //存放文件编译时间的字符串字面值
__DATE__    //存放文件编译日期的字符串字面值
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年08月27日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档