include
void assert (int expression);
虽然在cplusplus上面assert是这样子的,但是其实它是一个宏。
当assert的表达式(即参数expression)等于0或者为false时,assert会向stderr输出一些错误信息,并且调用abort终止程序运行。
assert输出的错误信息不同的库可能不一样,但是一般都会包含错误的表达式、源文件的名字、assert所在的行数。
同时,C++提供了另外一个宏 NDEBUG 用来使assert失效,需要添加在#include
已放弃
使用assert的缺点是,频繁的调用会极大的影响程序的性能,增加额外的开销。
在调试结束后,可以通过在包含#include
#include
#define NDEBUG
#include
VC中的写法:
#define ASSERT(f) \
do \
{ \
if (!(f) && AfxAssertFailedLine(THIS_FILE, __LINE__)) \
AfxDebugBreak(); \
} while (0) \
#define _ASSERT(expr) \
do { if (!(expr) && \
(1 == _CrtDbgReport(_CRT_ASSERT, __FILE__, __LINE__, NULL, NULL))) \
_CrtDbgBreak(); } while (0)
其他平台的写法:
# define ASSERT(x) ((x) || (dbg_printf("assertion failed ("__FILE__":%d): \"%s\"\n",__LINE__,#x), break_point(), FALSE))
CV_Assert是计算表达式 expression ,如果其值为假(即为 0),那么它先向 stderr 打印一条出错信息,然后抛出异常。注意:抛出异常。
这就是两者的区别,如果使用CV_Assert,我们可以通过捕获异常而不是程序崩溃,而assert会直接导致程序崩溃。
ASSERT是MFC中的,
两者都是在Debug下有效,在Release下,相当于没有,
#ifdef NDEBUG //NDEBUG是release,_DEBUG是debug #define assert(e) ((void)0) // 如果有定义NDEBUG宏,则assert断言不生效
VERIFY(wnd.create(...));
当debug、release下都运行 wnd.create(...) ,并在debug下断言是否成功。
#ifdef _DEBUG #define VERIFY(f) ASSERT(f) #else #define VERIFY(f) ((void)(f)) #endif
c++11引入了static_assert关键字,用来实现编译期间的断言,叫静态断言。
语法:static_assert(常量表达式,要提示的字符串);
如果第一个参数常量表达式的值为false,会产生一条编译错误,错误位置就是该static_assert语句所在行,第二个参数就是错误提示字符串。
然后通过调用 abort 来终止程序运行。
性能方面,由于是static_assert编译期间断言,不生成目标代码,因此static_assert不会造成任何运行期性能损失。
除了static_assert之外,c++还有assert和#error两个也是用来检查错误的。
error可看做预编译期断言,甚至都算不上断言,仅仅能在预编译时显示一个错误信息,它能做的不多,可以配合#ifdef/ifndef参与预编译的条件检查,由于它无法获得编译信息,当然就做不了更进一步分析了。
例如:
#ifndef __GNUC__ // 没有定义 __GNUC__ 宏,表示使用的不是gcc编译器
#error 代码中使用了 gcc 特有的扩展,必须使用 gcc 编译器编译
#endif
————————————————
参考:
https://blog.csdn.net/drdairen/article/details/76689014
https://www.cnblogs.com/htj10/p/13054290.html
https://blog.csdn.net/zhixiting5325/article/details/79785470
https://blog.csdn.net/x2017x/article/details/103384239
https://www.jianshu.com/p/435151c81abe