正确地 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__); 一样打电话。