喂!
我正在寻找一种方法来添加自定义消息来断言语句.我发现这个问题在断言中添加自定义消息?但那里的信息是静态的.我想做这样的事情:
assert((0 < x) && (x < 10), std::string("x was ") + myToString(x));
Run Code Online (Sandbox Code Playgroud)
当断言失败时,我想要正常输出加上例如"x为100".
我偶然发现了一篇内容丰富的文章:http://cnicholson.net/2009/02/stupid-c-tricks-adventures-in-assert/ ,它指出了我当前的调试宏套件中存在的大量问题.
如果您点击链接,则会在文章末尾附近给出宏的最终版本的完整代码.
提出的一般形式是这样的(如果我在转置它时错误,请有人纠正我):
#ifdef DEBUG
#define ASSERT(cond) \
do \
{ \
if (!(cond)) \
{ \
ReportFailure(#cond, __FILE__, __LINE__, 0); \
HALT(); \
} \
} while(0)
#else
#define ASSERT(cond) \
do { (void)sizeof(cond); } while(0)
Run Code Online (Sandbox Code Playgroud)
在考虑使用我所学的内容修改代码时,我注意到该文章的评论中发布了一些有趣的变体:
一个是你不能将这个宏与三元运算符(即cond?ASSERT(x):func())一起使用,并且建议if()用三元运算符和一些括号以及逗号运算符替换它.后来另一位评论者提供了这样的:
#ifdef DEBUG
#define ASSERT(x) ((void)(!(x) && assert_handler(#x, __FILE__, __LINE__) && (HALT(), 1)))
#else
#define ASSERT(x) ((void)sizeof(x))
#endif
Run Code Online (Sandbox Code Playgroud)
&&在这种情况下,我认为使用逻辑并且特别聪明,在我看来,这个版本比使用if甚至三元的版本更灵活?:.更好的是返回值assert_handler可用于确定程序是否应该停止.虽然我不确定它为什么(HALT(), 1)而不仅仅是HALT().
我忽略了第二个版本是否存在任何特殊缺点?它消除了do{ } …