向断言添加消息

tau*_*ran 41 c++ debugging logging assert

喂!

我正在寻找一种方法来添加自定义消息来断言语句.我发现这个问题在断言中添加自定义消息?但那里的信息是静态的.我想做这样的事情:

assert((0 < x) && (x < 10), std::string("x was ") + myToString(x));
Run Code Online (Sandbox Code Playgroud)

当断言失败时,我想要正常输出加上例如"x为100".

Kon*_*lph 70

你在这里运气不好.最好的方法是定义自己的assert宏.

基本上,它看起来像这样:

#ifndef NDEBUG
#   define ASSERT(condition, message) \
    do { \
        if (! (condition)) { \
            std::cerr << "Assertion `" #condition "` failed in " << __FILE__ \
                      << " line " << __LINE__ << ": " << message << std::endl; \
            std::terminate(); \
        } \
    } while (false)
#else
#   define ASSERT(condition, message) do { } while (false)
#endif
Run Code Online (Sandbox Code Playgroud)

这将定义ASSERT只有在没有调试宏宏NDEBUG没有定义.

然后你会像这样使用它:

ASSERT((0 < x) && (x < 10), "x was " << x);
Run Code Online (Sandbox Code Playgroud)

这比您的使用简单一点,因为您不需要字符串化"x was "x显式,这是由宏隐式完成的.

  • @tauran:所以你可以在宏之后使用分号. (6认同)
  • 可能不是那么多`asm("int 3")`,但``abort()`可能会更好. (5认同)
  • 为什么do {} while(false)? (4认同)
  • @Jon:取决于.请记住,`asm`一个不可移植(在MS编译器上,甚至不能在64版本中工作),但也取决于你运行代码的时间,地点和方式,你可能不想要它触发一个断点.(MS虽然具有`__debugbreak`内在功能,但它适用于所有MS平台)理想情况下,您可以使宏可配置,因此开发人员可以在编译时或运行时在中断和中断断言之间切换 (3认同)
  • 为什么不只是 {} 使它成为代码块?为什么要这样做? (2认同)
  • @Martin因为这样宏的使用必须以分号结束,这正是我们想要的。因此,在宏中使用“do…while”是一种既定模式。 (2认同)

Cam*_*ron 17

在没有编写自己的例程的情况下,有一些旧技巧可以包含消息:

首先是:

bool testbool = false;
assert(("this is the time", testbool));
Run Code Online (Sandbox Code Playgroud)

还有:

bool testbool = false;
assert(testbool && "This is a message");
Run Code Online (Sandbox Code Playgroud)

第一个起作用,因为内部parens表达式结果是'testbool'的值.第二个工作,因为字符串的值将是非零.


Als*_*lsk 9

更好的选择是教导调试器在失败时停止断言,然后您不仅可以检查x值,还可以检查包括调用堆栈在内的任何其他信息.也许,这就是你真正想要的.这里提到了示例实现方法向您的共同程序员展示在C++编程时某些方法尚未在类中实现


Alc*_*ive 6

#define ASSERT_WITH_MESSAGE(condition, message) do { \
if (!(condition)) { printf((message)); } \
assert ((condition)); } while(false)
Run Code Online (Sandbox Code Playgroud)

  • 这会评估条件两次,这可能会导致条件发生变化:`ASSERT_WITH_MESSAGE(++i == 10, "Ten")` (2认同)

sol*_*333 6

扩展康德拉德·鲁道夫的回答:

#include <iostream>

#ifdef NDEBUG
#define assert(condition, message) 0
#else
#define assert(condition, message)\
   (!(condition)) ?\
      (std::cerr << "Assertion failed: (" << #condition << "), "\
      << "function " << __FUNCTION__\
      << ", file " << __FILE__\
      << ", line " << __LINE__ << "."\
      << std::endl << message << std::endl, abort(), 0) : 1
#endif

void foo() {
   int sum = 0;
   assert((sum = 1 + 1) == 3, "got sum of " << sum << ", but expected 3");
}

int main () {
   foo();
}
Run Code Online (Sandbox Code Playgroud)

输出是...

Assertion failed: ((sum = 1 + 1) == 3), function foo, file foo.cpp, line 13.
got sum of 2, but expected 3
zsh: abort      ./a.out
Run Code Online (Sandbox Code Playgroud)

这类似于 std::assert 宏在我的系统上输出的内容,只是带有附加的用户定义消息