环境:
$ g++ --version
g++ (Ubuntu 7.4.0-1ubuntu1~18.04) 7.4.0
Run Code Online (Sandbox Code Playgroud)
众所周知,assert可以NDEBUG在包含assert.h(cassert)之前通过定义禁用用于调试的类函数宏。但是,/usr/include/assert.h在我的环境中阅读后,我发现了下面的代码。
#if defined __cplusplus && __GNUC_PREREQ (2,95)
# define __ASSERT_VOID_CAST static_cast<void>
#else
# define __ASSERT_VOID_CAST (void)
#endif
#ifdef NDEBUG
# define assert(expr) (__ASSERT_VOID_CAST (0))
# ifdef __USE_GNU
# define assert_perror(errnum) (__ASSERT_VOID_CAST (0))
# endif
#else /* Not NDEBUG. */
Run Code Online (Sandbox Code Playgroud)
因此,即使使用NDEBUG,assert也会扩展到某个值,从而对性能的影响微不足道,但可以肯定地(如果在预处理步骤之后未进行优化)。由于C ++标准允许类似函数的宏具有空值,因此似乎
#ifdef NDEBUG
#define assert(expr)
#endif
Run Code Online (Sandbox Code Playgroud)
将是一个很好的实现。
有什么理由可以选择非空值?
NDEBUG定义宏时具有值的原因之一是因为C标准要求它具有一个-甚至规定了它应该是什么。
¶1标头
<assert.h>定义assert和static_assert宏,并引用另一个宏,Run Code Online (Sandbox Code Playgroud)NDEBUG未由定义
<assert.h>。如果NDEBUG在包含源文件的位置将其定义为宏名称<assert.h>,则将assert宏定义为Run Code Online (Sandbox Code Playgroud)#define assert(ignore) ((void)0)
assert根据NDEBUG每次<assert.h>包含的当前状态重新定义该宏。¶2
assert宏应实现为宏,而不是实际功能。如果取消了宏定义以访问实际功能,则该行为未定义。…
概要
Run Code Online (Sandbox Code Playgroud)#include <assert.h> void assert(scalar expression);描述
¶2
assert宏将诊断测试放入程序中;它扩展为一个void表达式。执行它时,如果expression(应为标量类型)为false(即比较等于0),则assert宏将写入有关失败的特定调用的信息(包括自变量的文本,源文件的名称) ,源极线数,和包围函数的名称-后者分别是预处理的宏的值__FILE__和__LINE__与标识符的__func__)在一个实施方式定义的格式的标准错误流。191)然后调用该abort函数。退货
¶3
assert宏不返回任何值。191)编写的消息可能具有以下形式:
Run Code Online (Sandbox Code Playgroud)Assertion failed: expression, function abc, file xyz, line nnn.
C ++ 11标准说(§19.3断言)说:
标题
<cassert>…提供了用于记录C ++程序断言的宏以及用于禁用断言检查的机制。…
内容与标准C库标头相同
<assert.h>。
因此,相同的规则适用于C ++和C。C++标准未明确指出C ++ static_assert与C 之间的区别_Static_assert(以及标头C版本中static_assertas 的定义)。但是,最终结果大致相同。_Static_assert<assert.h>
| 归档时间: |
|
| 查看次数: |
247 次 |
| 最近记录: |