我在哪里可以找到类似于标准C ++库(在ASSERT
中定义的那个)的assert(...)
宏的<cassert>
,但是它也适用于Release模式?或者我应该怎么写?
我喜欢assert(...)
,因为它会自动打印断言失败的源文件行以及断言表达式。我期待发布模式ASSERT
中的那些功能(如果可能的话)。
基本上assert
是一个宏来评估表达式,如果它失败打印的东西,然后abort
s。写类似的东西并不难。
#define ASSERT(x) do { if( !(x) ) { printfunc( #x ); abort(); } while(0)
然后您可以修改它以满足您的要求。例如,您可能不希望在发布模式下使用abort
。您还可以调整打印输出(仅包括您认为有用的信息),以获取您将使用的文件和行信息__FILE__
和__LINE__
宏(顺便说一下,定义中的#x
扩展为包含表达式x
的字符串文字) )。
在发布版本中,不要定义NDEBUG
,assert
也可以。
你可以取消定义NDEBUG
#undef NDEBUG
在断言声明附近
或者你可以定义自己的断言
#define assert(x) printf(...)
基于这个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;
}
有了这种结构,你的实现也可以做一些关键的状态保存等(如果你认为你的程序状态值得信赖......有争议)。
在发布模式下使用std assert
(通过注释,您希望启用编译器优化),本身不是问题,正如其他答案所建立的那样。写一个自定义的已经完成,所以那里没有太多问题。
但是,引用Dr. Dobb's article:
在整个代码中使用断言;他们是警惕,可靠的警卫,保护您(您的程序)免受精神错乱
如果你担心断言+编译器优化,那么这两件事在概念上有点增加几率:
因此,总而言之,我看到使用了一个释放模式断言,但确保将它与“普通”断言分开,大多数人都认为它在释放模式下是关闭的。