断言在程序开发中的运用

    完整工程代码放在我的github上:https://github.com/yjwwyygy/CrossPlatformLibrary

    在程序开发中,经常会对一些错误进行处理,尤其是系统调用的返回值,一些致命或不应该出现的错误,如申请内存失败及其它系统错误,我们的程序应该做十分完备的处理,以达到程序的健壮性。

    断言在C/C++开发中是一个有用的利器,运用的好,可以大大的节省修复BUG的时间,C++中有更好的解决方案--异常,但它有一定的复杂性,本着简单的事情简单做的原则,我使用断言来处理。

    系统提供的断言错误信息太少,而且在其些编译器优化的情况下会被去掉,这里我自己定义一些断言处理,提供更详细的信息,主要处理以下错误:

    (1)普通断言。用于一般的逻辑处理。

    (2)errno样式的断言。一些系统调用出错返回-1,错误代码设置在全局变量errno中。

    (3)POSIX样式的断言。POSIX标准的系统调用,出错时返回非0错误码。

    (4)其它。如内存分配失败等。

整理好的代码如下:

#ifndef ERR_INCLUDED_H
#define ERR_INCLUDED_H

#include 
   
   
    
    
#include 
    
    
     
     
#include 
     
     
      
      
#include 
      
      
       
       
#include 
       
       
         #ifdef WIN32 #include "windows.h" #endif void safe_abort(const char *errMsg); // 基本的断言,与assert功能类似 #define base_assert(x) \ do \ { \ if (!(x)) \ { \ fprintf(stderr, "Assertion failed: %s (%s:%d)\n", #x, __FILE__, __LINE__); \ safe_abort(#x); \ } \ } while (false) #ifdef WIN32 // 将GetLastError对应的错误代码转换为错误信息 void win_error(char *buffer, size_t bufferSize); // Windows下的GetLastError样式的错误断言 #define win_assert(x) \ do \ { \ if (!(x)) \ { \ char errStr[256]; \ win_error(errStr, 256); \ fprintf(stderr, "Assertion failed: %s (%s:%d)\n", errStr, __FILE__, __LINE__); \ safe_abort(errStr); \ } \ } while (false) #endif // errno样式的错误断言 #define errno_assert(x) \ do \ { \ if (!(x)) \ { \ const char *errStr = strerror(errno); \ fprintf(stderr, "%s (%s:%d)\n", errStr, __FILE__, __LINE__); \ safe_abort(errStr); \ } \ } while (false) // POSIX样式的错误断言 #define posix_assert(x) \ do \ { \ if (x) \ { \ const char *errStr = strerror(x); \ fprintf(stderr, "%s (%s:%d)\n", errStr, __FILE__, __LINE__); \ safe_abort(errStr); \ } \ } while (false) // 内存分配失败的断言 #define alloc_assert(x) \ do \ { \ if (!(x)) \ { \ fprintf(stderr, "FATAL ERROR: OUT OF MEMORY (%s:%d)\n", \ __FILE__, __LINE__); \ safe_abort("FATAL ERROR: OUT OF MEMORY"); \ }\ } while (false) #endif 
       
      
      
     
     
    
    
   
   

#include "err.h"

void safe_abort(const char *errMsg)
{
#ifdef WIN32
	ULONG_PTR extra_info[1];
	extra_info[0] = (ULONG_PTR)errMsg;
	RaiseException(0x40000015, EXCEPTION_NONCONTINUABLE, 1, extra_info);
#else
	(void)errmsg_;
	abort();
#endif
}

#ifdef WIN32

void win_error(char *buffer, size_t bufferSize)
{
	DWORD errcode = GetLastError();
	DWORD rc = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
		FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errcode, MAKELANGID(LANG_NEUTRAL,
		SUBLANG_DEFAULT), buffer, (DWORD)bufferSize, NULL);
	base_assert(rc);
}

#endif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值