2017-03-16 39 views
-2

我想定义一个marco来“在控制台上打印并写入文件”。 下面是我的代码,可能有人告诉我为什么它会导致“Segmentation fault(core dumped)”。printf造成的宏分段错误

#define TRC_DP(fmt, args...) \ 
do {\ 
    FILE * fp = fopen("/home/debug.log","a+");\ 
    fprintf(fp,"TRC_DP(%s:%d):\t" fmt, __func__, __LINE__, ##args);\ 
    printf(fmt, ##args);\ 
    fclose(fp);\ 
}while(0); 
+4

该宏不应以分号结尾。 – pmg

+1

'arg ...'的使用不是标准C.即使你在标准C中有一个可变参数宏,没有人可以帮助你,除非你提供了导致错误的宏的使用示例。 – Peter

+0

你为什么要用宏做它?写一个_function_'int TRC_DP(const char *,...)',并在'myprintf'中使用'vsprintf'变体之一。 –

回答

3

这里有一些缺陷:

  • TRC_DP(fmt, args...)无效标准C.
  • The icky do-while(0) trick假定没有拖尾分号。
  • 您必须始终检查fopen是否成功。

像这样的东西可能会解决问题:

#define TRC_DP(fmt, ...) \ 
do {\ 
    FILE * fp = fopen("/home/debug.log","a+");\ 
    if(fp != NULL) { \ 
     fprintf(fp,"TRC_DP(%s:%d):\t" fmt, __func__, __LINE__, __VA_ARGS__); \ 
     printf(fmt, __VA_ARGS__);\ 
     fclose(fp);\ 
    } \ 
}while(0) 

然而,这是一些严重的丑陋的代码。如果必须的话,应该用函数替换它,并在运行时连接格式字符串。总体而言,您应尽可能避免使用可变参数函数或宏。它们不仅丑陋而且非常危险。可变参数的存在通常是糟糕的程序设计的强烈表现。

+0

它的工作原理。感谢您的回答和建议! –