gpt4 book ai didi

c - 为什么断言是宏而不是函数?

转载 作者:太空狗 更新时间:2023-10-29 16:17:19 24 4
gpt4 key购买 nike

我的讲师在类里面问过我,我想知道为什么它是宏而不是函数?

最佳答案

如果我们查看draft C99 standard,简单的解释就是标准要求assert 是一个宏。 (据我所知,这些部分在 draft C11 standard 中也是相同的) 7.2 部分 诊断 段落 2 说:

The assert macro shall be implemented as a macro, not as an actual function. If the macro definition is suppressed in order to access an actual function, the behavior is undefined.

为什么需要这个,Rationale for International Standard—Programming Languages—C 中给出的理由是:

It can be difficult or impossible to make assert a true function, so it is restricted to macro form.

这不是很有信息性,但我们可以从其他要求中看出原因。回到 7.21 说:

[...]If NDEBUG is defined as a macro name at the point in the source file where is included, the assert macro is defined simply as

#define assert(ignore) ((void)0)

The assert macro is redefined according to the current state of NDEBUG each time that is included.

这很重要,因为它允许我们以一种简单的方式在 Release模式下关闭断言,在 Release模式下您可能希望承担可能昂贵的检查成本。

第二个重要的要求是需要使用宏__FILE____LINE____func__,这在

7.2.1.1 断言宏 说:

[...] the assert macro writes information about the particular call that failed [...] the latter are respectively the values of the preprocessing macros __FILE_ _ and __LINE_ _ and of the identifier __func_ _) on the standard error stream in an implementation-defined format.165) It then calls the abort function.

其中脚注 165 说:

The message written might be of the form:

Assertion failed: expression, function abc, file xyz, line nnn.

将其作为宏允许宏 __FILE__ 等...在正确的位置进行评估,正如 Joachim 指出的那样,作为宏允许它插入原始的表达式 在它生成的消息中。

C++ 标准草案要求 cassert header 的内容与标准 C 库中的 assert.h header 的内容相同:

The contents are the same as the Standard C library header .

See also: ISO C 7.2.

为什么是 (void)0?

为什么要使用 (void)0 而不是其他什么都不做的表达式?我们可以想出几个原因,首先这是 7.2.1.1 节中的断言概要的样子:

void assert(scalar expression);

它说(强调我的):

The assert macro puts diagnostic tests into programs; it expands to a void expression.

表达式 (void)0 符合以 void 表达式 结束的需要。

假设我们没有这个要求,其他可能的表达式可能会产生不良影响,例如允许在 Release模式下使用 assert 而在 Debug模式下不允许使用,例如使用 plain 0将允许我们在赋值中使用 assert 并且在正确使用时可能会生成 expression result unused 警告。至于评论中建议使用复合语句,我们可以从C multi-line macro: do/while(0) vs scope block中看到。它们在某些情况下会产生不良影响。

关于c - 为什么断言是宏而不是函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25285557/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com