【问题标题】:Does assert() act as the identity function in release mode?assert() 是否在发布模式下充当身份函数?
【发布时间】:2018-08-31 14:47:10
【问题描述】:

This library 使用assert() 就好像它是发布模式下的标识函数(当定义了 NDEBUG 时)。问题是一些重要的代码是用assert() 包裹的,我的测试在发布模式下执行时触发了,因为这些重要的部分没有被调用。可以在here 找到一个这样的示例,其中随机字节生成器不会生成任何内容,并且会导致无限循环。

个人轶事:我不喜欢assert(),由于这些歧义问题,我个人不使用它。我听说很多项目都因此出现了严重的错误,最近是 EOS,当他们的单元测试没有检测到一些超出范围的数组时,因为 NDEBUG 是在发布模式下定义的并且它没有触发。在这一点上,文档似乎并不清楚。 assert() 是否完全充当身份?

这个库(libbtc)似乎被广泛使用,我不明白开发人员为什么这样做。这是一个可怕的错误,我应该分叉并删除所有这些断言吗?或者这是一些与 C++ 不兼容的 C 东西?有人可以在这里解释正确的行动方案吗?

我使用 clang 6。

【问题讨论】:

  • assert 用于检查永远不可能发生的情况实际上永远不会发生。它发现编程错误。如果断言在运行时可能由于用户输入或其他外部因素而失败,那么它一开始就不应该是断言。
  • 没有歧义;您描述的代码完全是错误的。
  • “由于这些歧义问题,我个人不使用它” - 使用 assert 通常是团队的选择。我知道不止一个团队同意发布带有断言启用的代码。在至少一个系统上,断言成为“看门狗”设计的一部分。在一项系统审查中,有 3000 多个断言,有
  • 请注意,在 release 中运行的断言(并始终返回其值)通常称为verify。所以if (verify(some_test())){ 是一个分支,如果失败则断言。

标签: c++ unit-testing c++11 assert


【解决方案1】:

来自https://en.cppreference.com/w/cpp/error/assert

如果NDEBUG 在源代码中包含<cassert> 的位置被定义为宏名称,则assert 什么都不做。

不要在assert 中添加任何您所依赖的副作用。它们不会在您编译发布时发生,并且会改变程序的行为。

【讨论】:

  • 所以github上的那个人搞砸了。我想我会保留我在那里提交的问题。谢谢。
【解决方案2】:

看起来库编写者滥用了断言并将功能代码放在不属于它的地方。 至于因为 assert() 的错误,它的发生是因为对其目的的误解或缺乏编程纪律。 assert() 用于验证不变量不会被破坏,而不是用于功能代码。 assert() 非常容易误用或用错地方。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-13
    • 1970-01-01
    • 2020-10-04
    • 1970-01-01
    • 1970-01-01
    • 2013-04-26
    • 1970-01-01
    • 2020-12-17
    相关资源
    最近更新 更多