C++ 断言(0)是什么意思?
我在一次考试中遇到了这样一个问题,我仍然不太确定如何回答。我知道断言是测试程序的方法,但是我不太确定断言(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
任何解释都很好,谢谢。它总是失败的。差不多就是这样。它总是会失败,原因与“assert(x==5)”在x=5时成功的原因相同 如果您需要一个应用程序,那么您会将其放入真正不应该发生的代码块中
switch(suit) {
case CLUB:
case DIAMOND:
case HEART:
case SPADE:
// ...
default:
assert(0);
}
C++标准将
\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