基本上,我有以下宏定义:
#include <stdio.h>
#define altErrMsg(x,y,z) x":"#y":"z
#define errMSG(x,y,z) altErrMsg(x,y,z)
#define __failure() errMSG(__FILE__,__LINE__,__FUNCTION__)
int
main (int argc, char **argv)
{
puts (__failure ());
return 0;
}
宏__failure()
应该以{{1}}的形式打印一些调试信息。为此,我使用了GCC的预定义宏"filename:line:function"
和__LINE__, __FILE__
。我使用了间接,以便在连接之前扩展预定义的宏。必须对__FUNCTION__
的扩展进行字符串化(使用参数名称前的__LINE__
)。
AFAIK,#
将扩展为类似:“test.c”“:”“20”“:”“main”将引用一个单独的字符串常量“test.c:20:main” 。但那并没有发生,相反,我遇到了错误:
__failure()
使用test.c:5:46: error: expected ‘)’ before ‘__FUNCTION__’
#define __failure() errMSG(__FILE__,__LINE__,__FUNCTION__)
^
test.c:3:35: note: in definition of macro ‘altErrMsg’
#define altErrMsg(x,y,z) x":"#y":"z
^
test.c:5:21: note: in expansion of macro ‘errMSG’
#define __failure() errMSG(__FILE__,__LINE__,__FUNCTION__)
^~~~~~
test.c:10:11: note: in expansion of macro ‘__failure’
puts (__failure ());
进行编译显示gcc -E
永远不会展开,最终字符串如下所示:__FUNCTION__
这是错误的语法但我不知道为什么会发生这种情况!
这种行为有解释吗?以及对问题的任何更正?
答案 0 :(得分:1)
C99介绍
__func__
,GCC长期提供__FUNCTION__
。这两个都是包含当前函数名称的字符串(存在轻微的语义差异;请参阅GCC手册)。 它们都不是宏; 预处理器不知道当前函数的名称。
不是宏 - 这就是宏扩展的原因。如果这是你的意图,它将无法工作。 (如你所见)。
解决方案是使用一个函数,您将传递这些东西并相应地打印它们。那会有用。
void my_log( const char * filename, int linenumber, const char * funcname){
fprintf(sdtout,"%s[%d]%s\n",filename, linenumber, funcname);
}
并调用my_log(__FILE__,__LINE__,__FUNCTION__);
。