Home > programming > printf like function

printf like function

在编写服务器端程序的代码的时候,打日志应该是一个必不可少的事情。使用c++流的方式是一个不错的选择,类型安全。但是总给人一种很不爽的感觉。因为好好的一段话被硬生生的分隔开了。例如:

logger.DEBUG<<"client ["<<client.ip<<":"<<client.port<<"] timed out due to no message in ["<<timeout_interval<<"]ms";

这样看起来远没有如下格式看起来舒服:


logger(DEBUG,"client [%s:%u] timed out due to no message in [%u]ms",client.ip.cstrt(),client.port,timeout_interval);

当然了,有利就有弊。如果用第二种方法的话,一不小心就会让程序崩溃。例如如果一个%s的地方被传入了一个int的值,或者传入了一个std::string但是没有加上.c_str().这个时候多会让你的程序死的很难看,严重的时候会让你的core dump的call stack看起来怪异无比,甚至无从下手。
不过还好的就是gcc下的有个extension可以帮我们在编译的时候检查传入的参数是否类型正确。方法如下:

#   define    PRINTFLIKE(m,n) __attribute__((format(printf,m,n)))

其中m是格式化字符串在参数列表中的位置,n是传入到格式化字符串的参数的其实位置


class Logger
{
...
void operator()( int level, const char* fmt, ... ) PRINTFLIKE(2,3)
...
};

这样编译器在编译的时候如果发现格式化字符串和传入参数的类型不匹配的时候就会出一个warning。就像下面这样,这会帮你挽回很多crash造成的损失的 …


t.cpp:6: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘long long int’

Categories: programming Tags:
  1. No comments yet.
  1. No trackbacks yet.