C接口和实现:为什么同时存在函数断言和宏断言?

时间:2014-03-26 05:04:53

标签: c macros

在“C接口和实现”4.3中,在assert.h中:

#undef assert
#ifdef NDEBUG
#define assert(e) ((void)0)
#else
#include "except.h"
extern void assert(int e);
#define assert(e) ((void)((e)||(RAISE(Assert_Failed), 0)))
#endif

extern void assert(int e);的目的是什么?因为在assert.c中,它是由assert宏实现的。

2 个答案:

答案 0 :(得分:0)

如果您仔细阅读本书的这一部分,您会发现它为assert()提供了标准接口,但未提供符合标准的实现。

  

Assert接口定义标准指定的assert(e),除了断言失败引发异常Assert_Failed而不是中止执行,并且不提供断言的文本ë

     

...从问题中显示的assert.h中提取......

     

assert模仿标准的定义,以便两个assert.h标题可以互换使用,这就是Assert_Failed出现except.h的原因。这个界面的实现是微不足道的:

     

assert.c

#include "assert.h"

const Except_T Assert_Failed = { "Assertion failed" };

void (assert)(int e) {
    assert(e);
}

您需要阅读本章的前面部分,以了解异常处理机制和Except_T(以及except.h)。

答案 1 :(得分:0)

虽然它看起来没有意义,但确实如此 - 至少在某些情况下。

assert()宏隐藏了标准定义,但仍有“后门”。

assert(1 == 0)

将调用宏,同时您仍然可以通过

到达原始功能(如果已定义)
(assert)(1 == 0)

(括号抑制宏扩展)。