shu*_*alo 2 c c++ debugging assert
目前,我写
assert(false);
Run Code Online (Sandbox Code Playgroud)
在我的代码永远无法到达的地方。一个非常C风格的示例是:
int findzero( int length, int * array ) {
for( int i = 0; i < length; i++ )
if( array[i] == 0 )
return i;
assert(false);
}
Run Code Online (Sandbox Code Playgroud)
一旦达到assert(false),我的编译器就会意识到程序已完成。但是,每当出于性能原因使用-DNDEBUG进行编译时,最后一个断言都会消失,并且编译器会警告执行将在没有return语句的情况下完成该函数。
如果已经达到了代码的一个所谓的无法到达的部分,那么完成程序的更好的替代方法是什么?解决方案应该
无论是现代C ++还是90s C,我都对解决方案特别感兴趣。
替换您的assert(false)内容正是“无法访问的”内置功能的目的。
它们在语义上等同于您对的使用assert(false)。实际上,VS的拼写非常相似。
GCC / C语/英特尔:
__builtin_unreachable()
Run Code Online (Sandbox Code Playgroud)
MSVS:
__assume(false)
Run Code Online (Sandbox Code Playgroud)
不管NDEBUG(与assert)或优化级别如何,它们都有效。
您的编译器,尤其是具有上述内置功能的编译器,也可能与您的一起使用assert(false),它的头是理解您承诺永远无法实现部分功能。它可以使用它在某些代码路径上执行一些优化,并且由于您已经保证它是故意的,因此它将使有关返回缺失的警告静音。
需要权衡的是,语句本身具有未定义的行为(就像已经存在并从函数末尾流出一样)。在某些情况下,您可能希望考虑引发异常(或返回一些“错误代码”值),或者std::abort()如果想终止程序,则调用(在C ++中)。
有一个建议(P0627R0),将其作为标准属性添加到C ++中。
如果控制流到达的位置,则
__builtin_unreachable该程序未定义。在编译器无法推断代码无法到达的情况下,此功能很有用。[..]
作为一个完全便携式的解决方案,请考虑:
[[ noreturn ]] void unreachable(std::string_view msg = "<No Message>") {
std::cerr << "Unreachable code reached. Message: " << msg << std::endl;
std::abort();
}
Run Code Online (Sandbox Code Playgroud)
当然,消息部分是可选的。
我喜欢用
assert(!"This should never happen.");
Run Code Online (Sandbox Code Playgroud)
...也可以与条件一起使用,如
assert(!vector.empty() || !"Cannot take element from empty container." );
Run Code Online (Sandbox Code Playgroud)
这样做的好处是,如果断言不成立,该字符串会显示在错误消息中。