2

这会发生吗?3 断言,一个应该激活的地方。

int nr = perform_calc();
assert( nr == 0);
assert( nr > 0);
assert( nr < 0);

是否存在程序未激活 g++ 3.4.4 上的断言的情况。

不,我无法更改代码以打印数字,以防断言未激活。

有任何想法吗?

编辑:在阅读了几条评论后,我被迫进行了编辑。显示代码?你为什么要做这种愚蠢的事情?我不相信!它在哪里使用?从我的问题来看,由于几个可能的原因,我不会发布/更改代码应该很明显:

  • 我是一个完全的初学者并且对代码感到羞耻(那里没有犯罪,如果我发布它肯定会让回答问题变得更加容易)
  • 我被要求帮助一个只有很少信息的朋友(不,我没有问他为什么你不能检查返回的数字,或者他为什么不能只添加一个断点)。
  • 我在没有任何编译器的情况下用 emacs 编写代码,并将其发送到远程服务器,该服务器对其进行编译、运行,并且只有在出现问题时才能返回失败的断言。

如果您认为我在进行恶作剧或恶作剧,您应该投票支持关闭该线程。我会很好的。但是像这样添加不必要的评论只会让我想要一个“态度”标志来实现。

我要感谢其他人的评论和回答,他们实际上试图解释和回答我的问题。

4

7 回答 7

14

assert如果NDEBUG定义了宏,则未选中。#undef NDEBUG在编译这个翻译单元时确保你。

您可以使用开关调用 gcc-E以验证您的断言语句是否仍在代码中。

于 2009-07-18T21:43:34.743 回答
13

正如我在生活中看到的如此丑陋的事情,如果 perform_calc() 有一个缓冲区溢出覆盖了堆栈中的返回地址,则可以解释这一点。当函数结束时,被覆盖的地址从堆栈中恢复并设置为当前 PC,导致跳转可能在程序的另一个区域,显然超过了断言调用。

虽然这是一个非常遥远的可能性,但它就是你所展示的。

另一种可能性是有人做了一个丑陋的宏把戏。检查你是否有类似的东西

#define assert 

或者一些同事在你上厕所的时候在标题中放了这样的东西

#define < ==
#define > ==

正如另一个答案中所建议的,使用 gcc -E 检查实际编译了哪些代码。

于 2009-07-18T21:45:24.240 回答
5

首先,该代码看起来不正确。如果调试已打开(设置了 DEBUG 和/或 _DEBUG 而未设置 NDEBUG):

assert( nr == 0);

如果 nr != 0,上述行将调用 exit()。因此,如果此行通过,第二个断言将执行:

assert( nr > 0);

...并调用 exit() 因为 nr == 0 和 !(nr > 0)。

assert( nr < 0);

而这第三行将永远不会运行。

确切地说,这段代码的重点是什么?如果可以添加这些断言,为什么不添加 printf()?

于 2009-07-18T21:52:36.130 回答
5

这段代码是多线程的吗?也许你有一个竞争条件

于 2009-07-18T21:57:34.233 回答
4

不,我没有可能更改代码以打印出数字..

奇怪的。您显然可以插入 assert() 语句,因为如果它们实际上是在您无法触及的真实代码中,则该代码可能无法工作。那么为什么不能打印 assert() 调用 test 的值呢?

于 2009-07-18T21:49:42.610 回答
1

我怀疑你在清理代码片段时不小心消除了这个问题。要么有更多代码(并且 nr 在断言之间发生了变化),要么实际上看起来不像那样(或者,根据 rlbond,您没有打开断言)。

尝试发布一个不太干净的代码段,让我们看看我们是否无法解决它。

于 2009-07-18T21:50:16.150 回答
-3

可能是NaN吗?在这种情况下,以下断言将失败:

assert( nr == nr );
于 2009-07-18T21:48:19.400 回答