可以在断言失败时记录信息,带有时间戳
离。
int a = 10
assert( a > 100 );
然后它将失败并输出就像时间戳一样
2013-12-02 , 17:00:05 assert failed !! (a > 100) line : 22
谢谢
答案 0 :(得分:5)
assert
是一个宏(必须是一个,才能提供__LINE__
和__FILE__
信息。
您可以定义自己的。出于可读性的原因,我会将其命名为tassert
,或许就像(未经测试的代码)
#ifdef NDEBUG
#define tassert(Cond) do {if (0 && (Cond)) {}; } while(0)
#else
#define tassert_at(Cond,Fil,Lin) do { if ((Cond)) { \
time_t now##Lin = time(NULL); \
char tbuf##Lin [64]; struct tm tm##Lin; \
localtime_r(&now##Lin, &tm##Lin); \
strftime (tbuf##Lin, sizeof(tbuf##Lin), \
"%Y-%m-%d,%T", &tm##Lin); \
fprintf(stderr, "tassert %s failure: %s %s:%d\n", \
#Cond, tbuf##Lin, Fil, Lin); \
abort(); }} while(0)
#define tassert(Cond) tassert_at(Cond,__FILE__,__LINE__)
#endif /*NDEBUG*/
我正在使用cpp concatenation ##
与Lin
一起降低名称冲突的可能性,我正在使用cpp stringification #
来制作一个字符串{ {1}}宏观正式。 Cond
始终展开,以确保编译器在其中捕获语法错误,即使在Cond
tassert
作为assert(3)禁用NDEBUG
时也是如此。
可以将上述宏中的大多数代码放在某些函数中,例如
void tassert_at_failure (const char* cond, const char* fil, int lin) {
timer_t now = time(NULL);
char tbuf[64]; struct tm tm;
localtime_r (&now, &tm);
strftime (tbuf, sizeof(tbuf), "%Y-%m-%d,%T", &tm);
fprintf (stderr, "tassert %s failure: %s %s:%d\n",
cond, tbuf, fil, lin);
abort();
}
然后定义(有点像<assert.h>
那样......)
#define tassert_at(Cond,Fil,Lin) do { if ((Cond)) { \
tassert_at_failure(#Cond, Fil, Lin); }} while(0)
但我不太喜欢这种方法,因为在gdb
调试时,在宏中调用abort()
要容易得多(用于调试可执行文件的代码的IMHO大小根本不重要;在abort
内调用宏中的gdb
更加方便 - 缩短回溯并避免一个down
命令...)。如果您不想要libc
可移植性并且只使用最近的GNU libc
,您可以简单地重新定义Glibc特定的__assert_fail
函数(请参阅<assert.h>
头文件内部)。 YMMV。
<<
来进行类似断言的调试输出。这可以使用我自己的operator <<
输出例程(如果你把它作为一个额外的宏参数),所以我在考虑(未经测试的代码!)
#define tassert_message_at(Cond,Out,Fil,Lin) \
do { if ((Cond)) { \
time_t now##Lin = time(NULL); \
char tbuf##Lin [64]; struct tm tm##Lin; \
localtime_r(&now##Lin, &tm##Lin); \
strftime (tbuf##Lin, sizeof(tbuf##Lin), \
"%Y-%m-%d,%T", &tm##Lin); \
std::clog << "assert " << #Cond << " failed " \
tbuf##Lin << " " << Fil << ":" << Lin \
<< Out << std::endl; \
abort (); } } while(0)
#define tassert_message(Cond,Out) \
tassert_message_at(Cond,Out,__FILE__,__LINE__)
然后我会使用tassert_message(i>5,"i=" << i);
顺便说一句,您可能希望在fprintf
宏中使用syslog(3)而不是tassert_at
。