gpt4 book ai didi

c++ - 为什么 `assert` 宏即使与 `NDEBUG` 也有值(value)?

转载 作者:可可西里 更新时间:2023-11-01 17:53:05 30 4
gpt4 key购买 nike

环境:

$ g++ --version
g++ (Ubuntu 7.4.0-1ubuntu1~18.04) 7.4.0

众所周知,在包含 assert.h 之前定义的 NDEBUG 可以禁用用于调试的类函数宏 assert (卡塞特)。但是,在我的环境中阅读 /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. */

因此,即使使用 NDEBUGassert 也会扩展为某个值,因此对性能的影响微不足道,但肯定会(如果在预处理步骤后没有进行优化)。由于 C++ 标准允许具有空值的类似函数的宏,看来

#ifdef NDEBUG
#define assert(expr)
#endif

会是一个很好的实现。

有什么理由可以选择非空值吗?

最佳答案

宏在 NDEBUG 时具有值的一个原因被定义是因为 C 标准要求它有一个——它甚至规定了它应该是什么。

C11

§7.2 Diagnostics <assert.h>

¶1 The header <assert.h> defines the assert and static_assert macros and refers to another macro,

    NDEBUG

which is not defined by <assert.h>. If NDEBUG is defined as a macro name at the point in the source file where <assert.h> 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 <assert.h> is included.

¶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.

7.2.1.1 The assert macro

Synopsis

    #include <assert.h>
void assert(scalar expression);

Description

¶2 The assert macro puts diagnostic tests into programs; it expands to a void expression. When it is executed, if expression (which shall have a scalar type) is false (that is, compares equal to 0), the assert macro writes information about the particular call that failed (including the text of the argument, the name of the source file, the source line number, and the name of the enclosing function -- 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.191) It then calls the abort function.

Returns

¶3 The assert macro returns no value.

191) The message written might be of the form:

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

C++11

C++11 标准说(§19.3 断言)说:

The header <cassert> … provides a macro for documenting C++ program assertions and a mechanism for disabling the assertion checks.

The contents are the same as the Standard C library header <assert.h>.

因此,适用于 C++ 的规则与适用于 C 的规则相同。C++ 标准并未明确指出 C++ static_assert 之间的差异。和 C _Static_assert (以及 static_assert_Static_assert header 的 C 版本中定义为 <assert.h>)。不过,最终结果大致相同。

关于c++ - 为什么 `assert` 宏即使与 `NDEBUG` 也有值(value)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56268229/

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