assert宏的不解
assert
C++ Utilities library Error handling
Defined in header <cassert>
#ifdef NDEBUG
#define assert(condition) ((void)0)
#else
#define assert(condition) /*implementation defined*/
#endif
The definition of the macro assert depends on another macro, NDEBUG, which is not defined by the standard library.
If NDEBUG is defined as a macro name at the point in the source code where <cassert> is included, then assert does nothing.
If NDEBUG is not defined, then assert checks if its argument (which must have scalar type) compares equal to zero. If it does, assert outputs implementation-specific diagnostic information on the standard error output and calls std::abort. The diagnostic information is required to include the text of expression, as well as the values of the standard macros __FILE__, __LINE__, and the standard variable __func__.
以上是
assert宏的一些解释
有几点不解:
1.void 的用法感觉不对, void不可以作为 类型来进行转换的
2.
If NDEBUG is defined as a macro name at the point in the source code where <cassert> is included, then assert does nothing.
这句话的意思是否是说, 其实 编译器所做工作紧紧是 检测而已, 如果发现assert这个宏被替换为: ((void)0),那么它不做任何提示。
如果发现这个宏为: 空白,那么则工作。 '
你看
#ifdef NDEBUG
这里不是空白,是((void)0)
#else
这里的宏其实是一个空白
#endif
[解决办法]
你的理解反过来了
If NDEBUG is defined as a macro name at the point in the source code where <cassert> is included, then assert does nothing.
如果有定义宏NDEBUG,则assert宏被替换为((void)0),也就是什么都不做(void强制转换是可以的,但这句表达式就不能用来做别的事情了,至于为什么要强制转换为void,是因为光一个0或者空白语句编译器会报警告),
否则,assert宏会工作,但具体的代码取决于编译器的实现(implementation defined)
[解决办法]
1. 不用去纠结了, 编译器说了算. 如果编译器不支持这种写法, 它所带的库必然会用另外的.
2. 发现 NDEBUG 宏, 不做任何事情. 否则, 这个宏做它该做的.
#define assert(condition) /*implementation defined*/ 这里不是空白, 是有 assert 的实现, 文档里面省略了的吧. 源代码是这样的:
#undef assert
#ifdef NDEBUG
#define assert(_Expression) ((void)0)
#else
#ifdef __cplusplus
extern "C" {
#endif
_CRTIMP void __cdecl _wassert(__in_z const wchar_t * _Message, __in_z const wchar_t *_File, __in unsigned _Line);
#ifdef __cplusplus
}
#endif
#define assert(_Expression) (void)( (!!(_Expression))
[解决办法]
(_wassert(_CRT_WIDE(#_Expression), _CRT_WIDE(__FILE__), __LINE__), 0) )
#endif /* NDEBUG */
or decltype, as the expression in a return statement (6.6.3) for a function with the return type void, or as
the operand of an explicit conversion to type cv void.
摘自c++11标准