c++ - C/C++ 中 assert(false) 的更好替代方案

标签 c++ c debugging assert

目前,我在写

assert(false);

在我的代码不应该到达的地方。一个非常 C 风格的例子是:

int findzero( int length, int * array ) {
  for( int i = 0; i < length; i++ )
    if( array[i] == 0 )
      return i;
  assert(false);
}

我的编译器识别出程序在达到 assert(false) 时结束。但是,每当我出于性能原因使用 -DNDEBUG 进行编译时,最后一个断言就会消失,并且编译器会警告执行完成函数而没有 return 语句。

如果已经达到了假定无法到达的代码部分,有什么更好的选择可以结束程序?解决方案应该

  • 被编译器识别并且不产生警告(如上面或其他警告)
  • 也许甚至允许自定义错误消息。

无论是现代 C++ 还是类似 90 年代的 C,我都对解决方案很感兴趣。

最佳答案

替换您的 assert(false) 正是“无法访问的”内置函数的用途。

它们在语义上等同于您对 assert(false) 的使用。事实上,VS 的拼写非常相似。

GCC/Clang/英特尔:

__builtin_unreachable()

MSVS:

 __assume(false)

无论 NDEBUG(与 assert 不同)或优化级别如何,这些都有效。

您的编译器,尤其是带有上述内置函数但也可能带有您的 assert(false) 的编译器,点头表示理解您 promise 那部分该功能将永远无法实现。它可以使用它对某些代码路径执行一些优化,并且它会消除有关丢失返回的警告,因为您已经 promise 这是故意的。

权衡是语句本身具有未定义的行为(很像前进和流出函数的末尾已经是)。在某些情况下,您可能希望考虑抛出异常(或返回一些“错误代码”值),或者如果您只想终止则调用 std::abort()(在 C++ 中)程序。


有一个提案(P0627R0),将其作为标准属性添加到 C++。


来自 the GCC docs on Builtins :

If control flow reaches the point of the __builtin_unreachable, the program is undefined. It is useful in situations where the compiler cannot deduce the unreachability of the code. [..]

关于c++ - C/C++ 中 assert(false) 的更好替代方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57908992/

相关文章:

c - gcc-arm 链接错误 : attempted static link of dynamic object

asp.net - 配置Visual Studio或Chrome以在同一新的浏览器窗口中启动多个Asp.Net项目

C++ 未定义引用

c++ - 为什么 clang 或 gcc 不标记这种从 double 到 int 的隐式转换?

c++ - pthread_cond_t 是一个对象还是什么?

c++ - 将类模板转换为 SFINAE 和构造函数委托(delegate),现在出现编译器错误

c - 从 C 中的函数返回 C 字符串

c - 如果指数是变量,为什么从 pow() 输出的超大值不以相同的方式强制转换?

debugging - cuda无限内核

android - 如何使用 Bluestacks 模拟器调试 Android Studio 项目?