gpt4 book ai didi

带时间戳的 C++ 断言

转载 作者:太空狗 更新时间:2023-10-29 20:41:37 24 4
gpt4 key购买 nike

是否可以在带有时间戳的断言失败时记录信息

例如

int a = 10

assert( a > 100 );

那么它将失败并像时间戳一样输出

2013-12-02 , 17:00:05 assert failed !! (a > 100) line : 22

谢谢

最佳答案

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 #Cond 制作一个字符串宏正式。 Cond始终展开,以确保即使禁用 tassert 编译器也能捕获其中的语法错误与 NDEBUG作为assert(3)

可以将上述宏中的大部分代码放在某个函数中,例如

 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()在宏中调用要容易得多(恕我直言,用于调试可执行文件的代码大小根本无关紧要;在宏中调用 abortgdb 内部更方便 - 缩短回溯并避免一个 down 命令.. .).如果你不想libc便携性,只需使用最新的 GNU libc您可以简单地重新定义 Glibc 特定的 __assert_fail函数(参见内部 <assert.h> 头文件)。 YMMV.

顺便说一句,在实际的 C++ 代码中我更喜欢使用 <<用于类似断言的调试输出。这允许使用我自己的 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);

顺便说一句,你可能想使用 syslog(3)而不是 fprintf在你的tassert_at宏。

关于带时间戳的 C++ 断言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20702852/

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