C++ C++;断言消息

C++ C++;断言消息,c++,assert,C++,Assert,我真的很快就想弄清楚断言的“自定义消息”是做什么的。我似乎找不到答案 即: 消息实际输出在哪里?因为当我尝试它时,它肯定不会显示。当您确定程序中的某个变量始终具有某个已定义的值/值范围,并且如果它采用任何其他值时,将使用断言消息,它应该指示代码中的错误,这将导致程序崩溃,并将打印断言消息 在您的情况下,当我运行您的代码时,我得到: a.out: del.c:7: main: Assertion `x > 0 && "Number must be above 0"' fail

我真的很快就想弄清楚断言的“自定义消息”是做什么的。我似乎找不到答案

即:


消息实际输出在哪里?因为当我尝试它时,它肯定不会显示。

当您确定程序中的某个变量始终具有某个已定义的值/值范围,并且如果它采用任何其他值时,将使用断言消息,它应该指示代码中的错误,这将导致程序崩溃,并将打印断言消息

在您的情况下,当我运行您的代码时,我得到:

a.out: del.c:7: main: Assertion `x > 0 && "Number must be above 0"' failed.
Aborted (core dumped)

因为
assert
通常是这样实现的(可能要复杂得多,但这里简化了)

#如果(!x){assert_fail(#x,_文件,_线___)}定义assert(x)
无效断言失败(常量字符*str,常量字符*文件,int行)
{

它本身不输出任何东西,但允许我们在检查时看到字符串。 基本上,因为字符串作为表达式是真的,所以我们可以将它标记到任何断言上,当表达式的另一部分失败时,它就会出现

因此,在断言打印到stderr的情况下(许多实现都是这样做的),输出类似于
断言'x>0&&“数字必须大于0”
,在unix平台上的大多数情况下都是这样


如果定义了NDEBUG,它将只是一个no-op并进行预处理。

只有编译器向您显示断言的确切条件时,它才有用,在这种情况下,您看到的字符串就在那里。那么我一定是做错了什么。当我准确地运行上述代码时,我的程序存在(应该存在),但我没有看到任何类型的错误消息(如您指定的)。@CristianC.:我运行了您的代码,并看到了断言消息(请参阅我更新的ans)在这种情况下,这是非常奇怪的。我没有看到消息。我会用谷歌搜索一下这个问题,看看我是否能给出任何明确的答案来解释原因。在这种情况下,字符串有什么用处?人们如何使用它?它会持续存在,并且取决于实现,它可以打印到stderr。例如,使用libstd++转储foll由于消息
断言x>0&“数字必须大于0”失败。已中止(内核转储)
在unix环境中,您可能会看到它是从带有调试版本的stderr打印出来的,请注意,如果定义了NDEBUG,则assert将被定义为no op。我没有看到在不报告文件和行号的情况下触发的assert。使用文件和行号,您可以检查文件并读取字符串。如果您不相信字符串或这是一个不充分的解释,接下来您可以在行上设置断点,运行到断言上的断点。并检查局部变量的原因。您是否已经将代码的性能与x为真时的性能进行了比较?[即,do nothing Other子句]我的断言测得较慢,我还没有弄清楚原因。(Ubuntu15.10,64位,c++v5)我看你没有else子句(和我的代码)有。很大程度上取决于您在
x
中所做的操作-如果这是对二叉树上的
find
的函数调用,然后再次调用
find
,则函数的性能减半。另一方面,如果
x
是一个
bool
int
已经从您无论如何都会使用的函数返回,开销很小(但不是零)。在某些情况下,开销来自编译器在不使用
assert
时能够更好地优化代码(对代码进行更多的重新排序,对计算进行向量化等)。一个空的
else
与编译器中的no-else相同。我想你是说你没有。无论如何,谢谢。我要测试的下一个“else子句”将是“static\u cast(0)”,上一个是“static\u cast(expr)”我没有,但是
static\u cast(expr)
应该根本不生成代码,因为这只是表示编译器使用了
expr
的一种方式。在某些情况下,它可以避免执行
int x=something();assert(x)
和编译器抱怨
x
未使用。当你说
else
时,你是指
else
对于配置了
NDEBUG
的情况吗?如果是,这是典型的实现,也是标准断言的规范。[现在,这与原始问题有点争议]
a.out: del.c:7: main: Assertion `x > 0 && "Number must be above 0"' failed.
Aborted (core dumped)
#define assert(x) if (!x) { assert_fail(#x, __FILE__, __LINE__); }

void assert_fail(const char *str, const char *file, int line)
{
  std::cerr << "Assertion failed " << str << " " << file << ":" << line << std::endl;
  abort();
}