首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

assert宏的困惑

2013-07-08 
assert宏的不解assertC++Utilities libraryError handling Defined in header cassert#ifdef NDEBUG#def

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 */


[解决办法]
引用:
Quote: 引用:

断言,如果程序运行到这,条件为假,不在往下执行了,里面的那个void可以是不需要的


引用:
你的理解反过来了
 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)



多谢

请教个问题:

void的类型的问题

(void)作为类型转换可以转换那些东西,比如后面,必须是数字吗?

这个有什么权威资料解释一些,
多谢


The void type has an empty set of values. The void type is an incomplete type that cannot be completed. It
is used as the return type for functions that do not return a value. Any expression can be explicitly converted
to type cv void (5.4).
 An expression of type void shall be used only as an expression statement (6.2), as an
operand of a comma expression (5.18), as a second or third operand of ?: (5.16), as the operand of typeid


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标准

热点排行