也适用于发布模式的ASSERT?

问题描述 投票:1回答:5

我在哪里可以找到类似于标准C ++库(在ASSERT中定义的那个)的assert(...)宏的<cassert>,但是它也适用于Release模式?或者我应该怎么写?

我喜欢assert(...),因为它会自动打印断言失败的源文件行以及断言表达式。我期待发布模式ASSERT中的那些功能(如果可能的话)。

c++ std assert
5个回答
3
投票

基本上assert是一个宏来评估表达式,如果它失败打印的东西,然后aborts。写类似的东西并不难。

#define ASSERT(x) do { if( !(x) ) { printfunc( #x ); abort(); } while(0)

然后您可以修改它以满足您的要求。例如,您可能不希望在发布模式下使用abort。您还可以调整打印输出(仅包括您认为有用的信息),以获取您将使用的文件和行信息__FILE____LINE__宏(顺便说一下,定义中的#x扩展为包含表达式x的字符串文字) )。


2
投票

在发布版本中,不要定义NDEBUGassert也可以。


1
投票

你可以取消定义NDEBUG

#undef NDEBUG

在断言声明附近

或者你可以定义自己的断言

#define assert(x) printf(...)

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;
}

有了这种结构,你的实现也可以做一些关键的状态保存等(如果你认为你的程序状态值得信赖......有争议)。


0
投票

在发布模式下使用std assert(通过注释,您希望启用编译器优化),本身不是问题,正如其他答案所建立的那样。写一个自定义的已经完成,所以那里没有太多问题。

但是,引用Dr. Dobb's article

在整个代码中使用断言;他们是警惕,可靠的警卫,保护您(您的程序)免受精神错乱

如果你担心断言+编译器优化,那么这两件事在概念上有点增加几率:

  • 断言应该并且可以自由使用,目的是尽早发现错误,并且主要是因为断言代码是否会损害性能并不重要。
  • 如果您希望/需要使用优化运行,您可能不喜欢其他(现在已优化但仍然)断言代码为您提供的性能。

因此,总而言之,我看到使用了一个释放模式断言,但确保将它与“普通”断言分开,大多数人都认为它在释放模式下是关闭的。

© www.soinside.com 2019 - 2024. All rights reserved.