我在哪里可以找到与标准C ++库(ASSERT
中定义的)assert(...)
宏类似的<cassert>
,但这也适用于发布模式?或者我该怎么写一个?
我喜欢assert(...)
,因为它会自动打印断言失败的源文件行以及断言表达式。我期望这些功能(如果可能的话)也在发布模式ASSERT
中。
答案 0 :(得分:3)
基本上assert
是一个用于评估表达式的宏,如果失败则打印一些内容然后abort
s。编写类似的东西并不难,比如。
#define ASSERT(x) do { if( !(x) ) { printfunc( #x ); abort(); } while(0)
然后您可以修改它以满足您的要求。例如,您可能不希望在发布模式下abort
。您还可以调整打印输出(仅包含您认为有用的信息),以获取您将使用__FILE__
和__LINE__
宏的文件和行信息(顺便提一下#x
在define中扩展为包含表达式x
)的字符串文字。
答案 1 :(得分:2)
在发布版本中,不要定义NDEBUG
,assert
也可以。
答案 2 :(得分:1)
您可以取消定义NDEBUG
#undef NDEBUG
在断言声明附近
或者您可以定义自己的断言
#define assert(x) printf(...)
答案 3 :(得分:0)
我已经推出了自己的断言,它总是在发布模式下启动,基于此article:
这是它的GIST,我没有提供实际的实现(AbstractAsserter,它基于这篇文章),但是你明白了:
#include <iostream>
struct AbstractAsserter
{
virtual void doAssert(const char* expr, const char* file, int line, const char* function) const
{
std::cout << "Asserting now at " << expr << ", " << file << ", " << line << ", " << function << std::endl;
}
};
struct Local
{
const char* function_;
const char* expr_;
const char* file_;
int line_;
Local( const char* f, const char* ex, const char* file, int line )
: function_( f ), expr_( ex ), file_( file ), line_( line )
{ }
Local operator << ( const AbstractAsserter& impl )
{
impl.doAssert( expr_, file_, line_, function_ );
return *this;
}
};
// More to be added as required...
#if defined( __GNUC__ )
# define WE_FUNCTION __PRETTY_FUNCTION__
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)
# define WE_FUNCTION __func__
#else
# define WE_FUNCTION "null_func()"
#endif
#define WE_ASSERT( expr )\
if( expr );\
else Local( WE_FUNCTION, #expr, __FILE__, __LINE__ )\
<< AbstractAsserter();
int main() {
WE_ASSERT(!"bad BAD BOY!");
return 0;
}
使用这种结构,你的实现也可以做一些关键的状态保存等(如果你认为你的程序状态值得信赖......有争议)。
答案 4 :(得分:0)
在发布模式下使用std assert
(通过注释,您希望启用编译器优化)本身并不是问题,正如其他答案所证实的那样。编写自定义脚本已经完成,因此那里没有太多问题。
但是,引用Dr. Dobb's article:
在整个代码中随意使用断言;他们是警惕,可靠的守卫,可保护您(您的程序)免于精神错乱
如果您担心需要使用断言和编译器优化,那么从概念上来说,这两件事有点增加几率:
因此,总而言之,我看到了释放模式断言的使用,但请确保将其与“正常”断言分开,在大多数人会认为“正常”断言处于释放模式的情况下。