gpt4 book ai didi

c++ - 自定义 C++ 断言宏

转载 作者:IT老高 更新时间:2023-10-28 12:50:30 30 4
gpt4 key购买 nike

我偶然发现了一篇内容丰富的文章: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)

在考虑用我学到的东西修改我的代码时,我注意到那篇文章的评论中发布了一些有趣的变化:

一个是您不能将此宏与三元运算符一起使用(即 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

我认为在这种情况下使用逻辑和 && 特别聪明,在我看来,这个版本比使用 if 甚至三元 ?:。更好的是,assert_handler 的返回值可以用来确定程序是否应该停止。虽然我不确定为什么它是 (HALT(), 1) 而不仅仅是 HALT()

我忽略的第二个版本有什么特别的缺点吗?它取消了包裹在宏周围的 do{ } while(0) 但这里似乎没有必要,因为我们不需要处理 ifs。

你怎么看?

最佳答案

在 C 和 C++ 标准库中,assert是充当函数所需的宏。该要求的一部分是用户必须能够在 表达式 中使用它。例如,使用标准 assert我可以的

int sum = (assert(a > 0), a) + (assert(b < 0), b);

功能相同

assert(a > 0 && b < 0)
int sum = a + b;

尽管前者可能不是编写表达式的好方法,但该技巧在许多更合适的情况下仍然非常有用。

这立即意味着如果一个人想要他们自己的定制ASSERT模仿标准的宏assert行为和可用性,然后使用 ifdo { } while (0)ASSERT 的定义中是没有问题的。一种仅限于这种情况下的表达式,即使用 ?:运算符或短路逻辑运算符。

当然,如果您不关心制作类似标准的自定义 ASSERT , 然后可以使用任何东西,包括 if .链接的文章似乎甚至没有考虑这个问题,这很奇怪。在我看来,类函数的断言宏肯定比非类函数的宏更有用。

至于(HALT(), 1) ... 这样做是因为 &&运算符需要一个有效的参数。 HALT()的返回值可能不代表 && 的有效参数.可能是 void据我所知,这意味着只有 HALT()根本不会编译为 && 的参数. (HALT(), 1)总是计算为 1并具有类型 int ,它始终是 && 的有效参数.所以,(HALT(), 1)始终是 && 的有效参数无论 HALT() 的类型如何.

您对 do{ } while(0) 的最后评论似乎没有多大意义。将宏包含在 do{ } while(0) 中的要点是处理外部if s,而不是 if s 在宏定义中。您总是必须处理外部 if s,因为您的宏总是有可能在外部 if 中使用.在后一个定义中 do{ } while(0)不需要,因为该宏是一个表达式。而且作为一个表达式,它与外部的if自然已经没有问题了。 s。所以,没有必要对它们做任何事情。此外,正如我上面所说,将其包含在 do{ } while(0) 中会完全违背它的目的,把它变成一个不表达的东西。

关于c++ - 自定义 C++ 断言宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5252375/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com