C++ 断言(0)是什么意思?

C++ 断言(0)是什么意思?,c++,c,assert,assertion,C++,C,Assert,Assertion,我在一次考试中遇到了这样一个问题,我仍然不太确定如何回答。我知道断言是测试程序的方法,但是我不太确定断言(0)正在检查什么。这是个骗人的问题吗?它总是会失败,但我不明白为什么。检查什么 任何解释都很好,谢谢。它总是失败的。差不多就是这样。它总是会失败,原因与“assert(x==5)”在x=5时成功的原因相同 如果您需要一个应用程序,那么您会将其放入真正不应该发生的代码块中 switch(suit) { case CLUB: case DIAMOND: case HEART: c

我在一次考试中遇到了这样一个问题,我仍然不太确定如何回答。我知道断言是测试程序的方法,但是我不太确定断言(0)正在检查什么。这是个骗人的问题吗?它总是会失败,但我不明白为什么。检查什么


任何解释都很好,谢谢。

它总是失败的。差不多就是这样。它总是会失败,原因与“assert(x==5)”在x=5时成功的原因相同

如果您需要一个应用程序,那么您会将其放入真正不应该发生的代码块中

switch(suit) {
  case CLUB:
  case DIAMOND:
  case HEART:
  case SPADE:
  // ...
  default:
    assert(0);
 }

C++标准将Asjt>/Cult>的定义推迟到C标准。

C99§7.2/2: 断言宏将诊断测试放入程序中;它扩展为一个空表达式。执行时,如果表达式(应具有标量类型)为false(即比较值等于0),则assert宏将写入有关失败的特定调用的信息(包括参数的文本、源文件的名称、源行号和封闭函数的名称——后者分别是预处理宏
\uuuuu file\uuuu
\uuuu line\uuu
的值以及标识符
\uu func\uu
的值)以实现定义的格式在标准错误文件上。然后调用
abort
函数


assert(0)
中,
0
被解释为
false
,因此当启用断言检查时,此断言将始终失败,或激发

因此,它断言

“执行永远不会达到这一点。”

在实践中,很难让编译器对达到或未达到给定点的执行关闭。通常,编译器会首先抱怨执行可能到达函数末尾而不返回值。添加
assert(0)
理想情况下应该解决这个问题,但是编译器可能会抱怨
断言,或者没有意识到它说您已经很清楚它试图警告什么

一(1)种可能的措施是在该点也抛出异常:

auto foo( int x )
    -> int
{
    if( x == 1 ) { return 42; }
    assert( 0 ); throw 0;       // Should never get here!
}
当然,这种双重打击可以定义为更高级别的宏。关于异常类型,您可能希望将其保留为非
std::exception
,因为这不是普通
catch
在任何地方捕获的异常。或者,如果您信任标准异常层次结构(这对我来说没有意义,但是)您可以使用
std::logic\u错误


要关闭
assert
assertion检查,您可以先定义符号
NDEBUG
,然后再包含
,以讨论另一种可能性,即特定于g++的内在
\uuuuuuuuuu内置
是的,它总是会失败

assert(0)
assert(false)
通常用于标记不可访问的代码,以便在调试模式下发出诊断消息,并在实际到达假定不可访问的代码时中止程序,这是一个明确的信号,表明程序没有做我们认为是做的事情。

此外还有其他答案(特别是一个)如果您使用的是最近的(或),您可能会考虑使用一些,特别是SuxBuuTiNixUnReabable()/<代码>而不是<代码> AsScript(0).P/> 有一些区别:首先,
assert
可以通过
-DNDEBUG
禁用。而
\u builtin\u unreachable
将改变编译器优化代码的方式

当然,有些编译器不知道
\u内置的\u不可访问的

您还可以考虑调用一些<代码> [[Norduturn] ] < /C> C++函数(C++ 11或更好)-或例如,<代码>流产()> <代码> < /P>


顺便说一句,
assert(0)
并不完全像抛出一些异常(因为可以捕获异常)

但通常断言是一个条件,对吗?那么如果只有“0”意味着什么呢?@zero是一个总是错误的条件,就像“现在的时间就是现在”一样是一个始终为真的条件。这应该是“每当x!=5”@SmithWestern如果(0)printf(“你好”);否则printf(“再见”);
do?@SmithWestern C中没有布尔类型,所以“false”为零,“true”的任何非零值使用更多感叹号:assert(!!!“你希望不会发生的事情。它就发生了”);注意使用单数。考虑到特里·普拉切特的即兴评论,“多个感叹号,”他摇着头继续说,“肯定是一个有病的头脑的标志。”而这3个感叹号肯定是“多个”,唯一的解决办法就是1。无论如何,我记得安德烈·亚历山德雷斯库和我未能就最佳方式达成一致。安德烈赞成
assert(“Blah”和&condition)
,而我赞成
assert((“Blah”,condition))
(我们都不赞成惊叹号)今天我使用
&&
,因为它更简单,更容易摸索。但这就是为什么我喜欢
(())
…值得注意的是,assert可以被禁用:无论是否有assert,您的代码流都应该是相同的!assert发出一个信号IIRC,实际上可能会被捕获。@black:它调用
abort
。能否拦截
abort
的操作是一个实现细节。不,IIRC,是
assert的实现
(或
abort
)在发出信号之前将信号处理程序重置为默认行为。您可以捕获信号,但仍然无法从信号中返回,即程序将被终止;
abort
确实标记为
[[noreturn]]
。都可以在手册页中找到。@cheers-sandhth.-Alf:而且,这种行为似乎定义得很清楚。_builtin_unreachable是非常非常重要的
#include <stdexcept>        // std::logic_error
#include <assert.h>

#undef ASSERT_SHOULD_NEVER_GET_HERE
#ifdef NDEBUG
#   define ASSERT_SHOULD_NEVER_GET_HERE() \
        throw std::logic_error( "Reached a supposed unreachable point" )
#else
#   define ASSERT_SHOULD_NEVER_GET_HERE() \
        do{ \
            assert( "Reached a supposed unreachable point" && 0 ); \
            throw 0; \
        } while( 0 )
#endif