正确地 Stringinize 和 concat 宏参数
Stringinize and concat macro parameters correctly
基本上,我有以下宏定义:
#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()
应该以 "filename:line:function"
的形式打印一些调试信息。为此,我使用了 GCC 的预定义宏 __LINE__, __FILE__
和 __FUNCTION__
。我使用了间接寻址,这样预定义的宏将在连接之前展开。 __LINE__
的扩展必须被字符串化(在参数名称前使用 #
)。
AFAIK,__failure()
将被扩展为类似这样的东西:"test.c"":""20"":""main" 将被引用到一个字符串常量 "test.c:20:main" 中。但这并没有发生,相反,我收到了错误:
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__
永远不会扩展,最终字符串如下所示: "test.c"":""22"":"__FUNCTION__
这是一个错误的语法,但我不知道为什么会这样!
这种行为有解释吗?以及对问题的任何更正?
如果你问为什么那么从Predefined macros
C99 introduced __func__
, and GCC has provided __FUNCTION__
for a long time. Both of these are strings containing the name of the current function (there are slight semantic differences; see the GCC manual). Neither of them is a macro; the preprocessor does not know the name of the current function.
不是宏 - 这就是宏没有展开的原因。如果这是您的意图,它将无法正常工作。 (如你所见)。
解决方案是使用一个函数,您可以在其中传递这些内容并相应地打印它们。那行得通。
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__);
一样打电话。
基本上,我有以下宏定义:
#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()
应该以 "filename:line:function"
的形式打印一些调试信息。为此,我使用了 GCC 的预定义宏 __LINE__, __FILE__
和 __FUNCTION__
。我使用了间接寻址,这样预定义的宏将在连接之前展开。 __LINE__
的扩展必须被字符串化(在参数名称前使用 #
)。
AFAIK,__failure()
将被扩展为类似这样的东西:"test.c"":""20"":""main" 将被引用到一个字符串常量 "test.c:20:main" 中。但这并没有发生,相反,我收到了错误:
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__
永远不会扩展,最终字符串如下所示: "test.c"":""22"":"__FUNCTION__
这是一个错误的语法,但我不知道为什么会这样!
这种行为有解释吗?以及对问题的任何更正?
如果你问为什么那么从Predefined macros
C99 introduced
__func__
, and GCC has provided__FUNCTION__
for a long time. Both of these are strings containing the name of the current function (there are slight semantic differences; see the GCC manual). Neither of them is a macro; the preprocessor does not know the name of the current function.
不是宏 - 这就是宏没有展开的原因。如果这是您的意图,它将无法正常工作。 (如你所见)。
解决方案是使用一个函数,您可以在其中传递这些内容并相应地打印它们。那行得通。
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__);
一样打电话。