zoukankan      html  css  js  c++  java
  • 断言assert()与调试帮助

    • 列表内容assert()是一种预处理宏(preprocessor marco),使用一个表达式来作为条件,只在DEBUG模式下才有用。
    assert(expr);
    

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

    #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仍然会执行。
    #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>
    // cassert standard header
    // NOTE: no include guard
    #include <yvals.h>
    #include <assert.h>
    
    
    //
    // 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,但是这个时候检查已经开始了,所以这一句也没用了。

    • 辅助诊断变量,均在预处理器中定义.
    __FILE__	//存放文件名的字符串字面值
    __LINE__	//存放当前行号的整型字面值
    __TIME__	//存放文件编译时间的字符串字面值
    __DATE__	//存放文件编译日期的字符串字面值
    
  • 相关阅读:
    Android实现监测网络状态
    安卓开源库之动画篇
    安卓向服务器发送List数据
    Material Design综合实例
    Material Design入门(三)
    Android之Fragment(二)
    Android之Fragment(一)
    Material Design入门(二)
    Material Design入门
    Android之ActionBar
  • 原文地址:https://www.cnblogs.com/FlyerBird/p/9541904.html
Copyright © 2011-2022 走看看