日志打印接口 编译时出现:error: ‘va_start’ used in function with fixed args

achilcs 2013-04-09 03:10:28
现在 在写一个日志接口:
主要想采用vsnprintf 和va_start() 系统调用, 基本要实现类似下面的功能;但是每次日志打印testlog.c和TLOGDEBUG(),这些是日志接口的信息,而非调用接口处的文件和函数。
[debug][2013-04-09 14:18:20] [testlog.c:TLOGDEBUG():189]

出现上面情况主要是把__FILE__,__FUNCTION__,__LINE__封装到日志接口函数内部实现中,未了避免是上面情况,把__FILE__等信息作为入参传入日志接口中。先定义两个宏,但是编译时出现error: ‘va_start’ used in function with fixed args。不知道什么原因?大家请帮忙看下,对下面的定义,大家有什么好的想法可以绕过这个坑。


83 #define LOGDEBUG(File,Func,Line,fmt, ...) do { \
84 va_list ap; \
85 va_start(ap, fmt); \
86 LOGFUNC(File, Func, Line,fmt,ap,Debug );\
87 va_end(ap); \
88 } \
89 while(0)
90
91
92 #define TLOGDEBUG(fmt, ... )do { \
93 LOGDEBUG(__FILE__,__FUNCTION__,__LINE__,fmt, ...); \
94 } \
95 while(0)
96

测试函数为:
int main()
{
16 TLOGDEBUG("firsstefadfoasdnf");
}

其中 LOGFUNC()函数是将buf写到文件中。
...全文
3385 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
achilcs 2013-04-09
  • 打赏
  • 举报
回复
根据上面的提示和自己分别测试, 深刻体会到 fdl19881提出 宏和函数可变函数的处理是不太一样的话。之前以为 va_start/vsprintf()和 __VLOGFUNC(A_ARGS__, ##args 等是可以相互替代的关心,现在发现前者应用自定义可变参数函数内部, 比如: EnumRet LOGFUNC(EnumLogLevel logLevel, Int8 *pFName, Int8 *pFunName, Int32 Line, Int8 *pFormatData, ...); 内部处理只能用va_start ,vsnprintf()系统函数。 后者应用于自定义的宏接口上: 比如 93 #define TLOGDEBUG(fmt, ...) do { \ 94 LOGFUNC(Debug, __FILE__,__FUNCTION__,__LINE__,fmt, __VA_ARGS__); \ 95 } \ 96 while(0) 恩,,谢谢 justkk 和fdl19881解答。 经测试 可以达到预先的要求, 测试实例: int main() { int maxv, x,y; 17 x =10; 18 y=20; 19 while(1) 20 { 21 maxv =mymax(x,y); 22 TLOGDEBUG(" %d max in {%d,%d}", maxv,x,y); 23 sleep(1); 24 // printf("max: %d, x: %d, y: %d,x: %d, y: %d \n",maxv, x,y,x,y); 25 26 } } 测试打印结果: [debug][2013-04-09 17:33:20] [testlogmain.c:main():22] 20 max in {10,20} [debug][2013-04-09 17:33:21] [testlogmain.c:main():22] 20 max in {10,20} [debug][2013-04-09 17:33:22] [testlogmain.c:main():22] 20 max in {10,20} [debug][2013-04-09 17:33:23] [testlogmain.c:main():22] 20 max in {10,20} [debug][2013-04-09 17:33:24] [testlogmain.c:main():22] 20 max in {10,20} [debug][2013-04-09 17:33:25] [testlogmain.c:main():22] 20 max in {10,20} [debug][2013-04-09 17:33:26] [testlogmain.c:main():22] 20 max in {10,20} [debug][2013-04-09 17:33:27] [testlogmain.c:main():22] 20 max in {10,20} [debug][2013-04-09 17:33:28] [testlogmain.c:main():22] 20 max in {10,20} [debug][2013-04-09 17:33:29] [testlogmain.c:main():22] 20 max in {10,20} [debug][2013-04-09 17:33:30] [testlogmain.c:main():22] 20 max in {10,20} [debug][2013-04-09 17:33:31] [testlogmain.c:main():22] 20 max in {10,20} [debug][2013-04-09 17:33:32] [testlogmain.c:main():22] 20 max in {10,20} [debug][2013-04-09 17:33:33] [testlogmain.c:main():22] 20 max in {10,20} [debug][2013-04-09 17:33:34] [testlogmain.c:main():22] 20 max in {10,20} [debug][2013-04-09 17:33:35] [testlogmain.c:main():22] 20 max in {10,20}
qq120848369 2013-04-09
  • 打赏
  • 举报
回复
怎么那么绕呢。。。 楼主貌似没理解为什么要用宏啊。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void log_write(const char *log)
{
    printf("%s\n", log);
}

void log_debug(const char *file, const char *func, int line, const char *log)
{
    printf("[%s %s %d] %s\n", file, func, line, log);
}

#define _DEBUG

#ifdef _DEBUG
    #define LOG(log) log_debug(__FILE__, __FUNCTION__, __LINE__, log)
#else
    #define LOG(log) log_write(log)
#endif

int main(int argc, char *const argv[])
{ 
    LOG("hello");
    return 0;
}
这不就是所有log库做的所有事情吗?
fdl19881 2013-04-09
  • 打赏
  • 举报
回复
可变参数宏有几种表示方法: http://hi.baidu.com/funrole/item/a73def03a0d3fadf72e67603
fdl19881 2013-04-09
  • 打赏
  • 举报
回复 1
宏的可变参数不是这么用的. 和函数的可变参数是不同的... 给楼主一个例子: 看看吧,
int log_open(const char *name);
void log_message(int priority ,const char* fmt, ...);
void log_trace(const char *file , int line , const char *func, const char *     fmt ,...);
int log_close();

#define LOG_ERROR(fmt , args...)    \
    log_message(LOG_PRI_ERROR, fmt, ##args)
#define LOG_WARN(fmt, args...)      \
    log_message(LOG_PRI_WARN, fmt , ##args)
#define LOG_NOTICE(fmt , args...)   \
    log_message(LOG_PRI_NOTICE, fmt , ##args)
#define LOG_DEBUG(fmt , args...)    \
    log_message(LOG_PRI_DEBUG, fmt , ##args)
#define LOG_TRACE(fmt,args...)      \
    log_trace(__FILE__ , __LINE__ , __FUNCTION__ , fmt ,## args)
justkk 2013-04-09
  • 打赏
  • 举报
回复
LOGFUNC自身应该是支持可变参数的函数,类似printf
achilcs 2013-04-09
  • 打赏
  • 举报
回复
恩啊。。刚才改动后不在再同一地方,现在改过了,,而且既然不用了va_start, 对于日志信息的刷写就不用vsprintf()接口函数,直接改为 sprintf(****,__VA_ARGS__)即可,这使得我修改内部函数的实现。 现在改为接口为: 93 #define TLOGDEBUG(fmt, ...) do { \ 94 LOGFUNC(Debug,__FILE__,__FUNCTION__,__LINE__, fmt, __VA_ARGS__); \ 95 } \ 96 while(0) 现在又出现一个问题: int main() { int x =10, y=20; int maxv =maxfunc(x,y); TLOGDEBUG(" %d max in {%d,%d}", maxv,x,y); } 打印显示 [debug][2013-04-09 16:29:17] [testlogmain.c:main():22] 20 max in {134517111,-1074988204} [debug][2013-04-09 16:29:18] [testlogmain.c:main():22] 20 max in {134517111,-1074988204} [debug][2013-04-09 16:29:19] [testlogmain.c:main():22] 20 max in {134517111,-1074988204} [debug][2013-04-09 16:29:20] [testlogmain.c:main():22] 20 max in {134517111,-1074988204} [debug][2013-04-09 16:29:21] [testlogmain.c:main():22] 20 max in {134517111,-1074988204} [debug][2013-04-09 16:29:22] [testlogmain.c:main():22] 20 max in {134517111,-1074988204} [debug][2013-04-09 16:29:23] [testlogmain.c:main():22] 20 max in {134517111,-1074988204} [debug][2013-04-09 16:29:24] [testlogmain.c:main():22] 20 max in {134517111,-1074988204} [debug][2013-04-09 16:29:25] [testlogmain.c:main():22] 20 max in {134517111,-1074988204} [debug][2013-04-09 16:29:26] [testlogmain.c:main():22] 20 max in {134517111,-1074988204} [debug][2013-04-09 16:29:27] [testlogmain.c:main():22] 20 max in {134517111,-1074988204} [debug][2013-04-09 16:29:28] [testlogmain.c:main():22] 20 max in {134517111,-1074988204} [debug][2013-04-09 16:29:29] [testlogmain.c:main():22] 20 max in {134517111,-1074988204} [debug][2013-04-09 16:29:30] [testlogmain.c:main():22] 20 max in {134517111,-1074988204} [debug][2013-04-09 16:29:31] [testlogmain.c:main():22] 20 max in {134517111,-1074988204} [debug][2013-04-09 16:29:32] [testlogmain.c:main():22] 20 max in {134517111,-1074988204} 对于LOGFUNC(EnumLogLevel logLevel, Int8 *pFName, Int8 *pFunName, Int32 Line, Int8 *pFormatData, Int8 *ap)调用, 我把 __VA_ARGS__作为 Int8*ap的形参,但是我在这个函数内部打印该ap时,出现非法访问,所以对于__VA_ARGS__作为入参,它对应的形参数是什么类型?
justkk 2013-04-09
  • 打赏
  • 举报
回复
你看仔细了,TLOGDEBUG宏没有使用LOGDEBUG。。
achilcs 2013-04-09
  • 打赏
  • 举报
回复
你的意思是用__VA_ARGS__ 替代 84 va_list ap; \ 85 va_start(ap, fmt); \ 这些 改动后编译: 91 #define TLOGDEBUG(fmt, ...) do { \ 92 LOGDEBUG(__FILE__,__FUNCTION__,__LINE__,fmt,__VA_ARGS__); \ 93 } \ 94 while(0) 95 编译 后结果还是 和之前一样: : error: ‘va_start’ used in function with fixed args 看似问题不是在这里,继续找解决方法
justkk 2013-04-09
  • 打赏
  • 举报
回复
试试

#define TLOGDEBUG(fmt, ... )do { \
LOGFUNC(__FILE__,__FUNCTION__,__LINE__,fmt, __VA_ARGS__); \
} \
while(0)

不用定义那个LOGDEBUG

23,223

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧