#if defined NDEBUG
#define assert(condition) ((void) 0)
#else
#define assert(condition) _assert((condition), #condition, __FILE__, __LINE__)
#endif (译注:assert的实现并不唯一,比如:
Visual C++ 6.0的实现是:
#define assert(exp) (void)((exp)||(_assert(#exp, __FILE__, __LINE__), 0));
Borland C++ 5.5的实现是:
#define assert(exp) ((exp) ? (void)0 : _assert(#exp, __FILE__, __LINE__))
至于函数_assert(在gcc的库中_assert是一个宏)是各家的内部实现,不一定得非要_assert这个名字,其内容一般是利用printf函数(在WIN平台上往往是调用MessageBox)输出出错信息(文件名及行号)并调用abort终止程序。
//*******************************************************//
在这个定义里,当定义了预处理符号NDEBUG的时候,断言是无效的,这意味着assert断言宏只在你的Debug版本中有效。在Release版本里,assert断言宏不进行任何计算。由于这个而会引起一些侧面效里,比如:
/* debug version */
#undef NDEBUG
#include <assert.h>
#include <stdio.h>
int main(void)
{
int i = 0;
assert(++i != 0);
printf("i is %d\n", i);
return 0;
}
/* 当运行后输出:
i is 1
*/
那么现在改变代码版本到release版本,定义NDEBUG:
/* release version */
#defing NDEBUG
#include <assert.h>
#include <stdio.h>
int main(void)
{
int i = 0;
assert(++i != 0);
printf("i is %d\n", i);
return 0;
}
/* 当运行后输出:
i is 0
*/
因此在assert中只能是比较而不能有实质性的动作,否则调试和发布版的结果可能会大相径庭。
因此,为了避免这种差异,确保在assert表达式不能包含有侧面影响的代码。
(译注:切记assert中不能存在任何实质性的动作。Microsoft提供了ASSERT和VERIFY等等宏,其中VERIFY可以用在发布版内,不过这既非C/C++标准,功能亦不够强大。)
只在Debug版本里,assert会调用_assert函数。以下是相似代码:
void _assert(int test, char const *test_image,
char const *file, int line)
{
if (!test)
{
printf("Assertion failed: %s, file %s, line %d\n",
test_image, file, line);
[ft=,,] a
最新评论