我可以将__func__替换为C宏中的标识符名称吗?

我想写一个C宏,它采用这个:

int foo() { MY_MACRO } 

并将其扩展为:

 int foo() { _macro_var_foo++; } 

我发现我不能使用__func__ ,因为它实际上并没有在宏中扩展; 它被预处理器像变量一样对待。

有没有办法让这个工作?

预处理器不知道函数,只知道源文件和行号。 在那个阶段,它不执行语法分析,只进行文本分析和替换。 这就是为什么__func__是一个神奇的变量,而不是像__FILE____LINE__这样的神奇宏。

在C99标准中, __func__被赋予一个特殊的新类别“预定义标识符”(在第__func__节预定义标识符中):

标识符__func__应由翻译器隐式声明,就像紧跟在每个函数定义的__func__大括号后面的声明一样

  static const char __func__[] = "function-name"; 

出现了,其中function-name是词法封闭函数的名称

这意味着它超出了C预处理器的范围,它不知道函数边界或函数名称。 此外,它将扩展为字符串,这使得嵌入变量名称不合适。


GCC(4.4.1)手册在5.43节(函数名称为字符串)中说明:

这些标识符[含义__func__ __FUNCTION____PRETTY_FUNCTION____PRETTY_FUNCTION__ ]不是预处理器宏。 在GCC 3.3及更早版本中,仅在C中, __FUNCTION____PRETTY_FUNCTION__被视为字符串文字; 它们可以用于初始化char数组,它们可以与其他字符串文字连接。 GCC 3.4及更高版本将它们视为变量,如__func__ 。 在C ++中, __FUNCTION____PRETTY_FUNCTION__一直是变量。

如果有一种方法可以将函数名称干净地放入预处理器中,那么如果它没有定义它,那么这里的文档很可能会交叉引用它。

从技术上讲,你的问题的答案是“是”,有“某种方式”。 但我认为你已经知道了,而且在宏预处理器级别你无法处理这个问题。

当然,总有一种方法,你可能需要在图灵机上使用一个非常长的磁带。

我想你已经知道了,但是为了记录你可以得到你想要的整体结果:

 #define MY_MACRO f_dictionary(__func__, ADDONE); 

所以现在,您只需要为它实现f_dictionaryADDONE操作。

您可以使用令牌连接执行此操作。

 #define MY_MACRO(baz) _macro_var_##baz++; #define FUNC_WRAPPER(bar)\ int bar()\ {\ MY_MACRO(bar)\ } FUNC_WRAPPER(foo) 

gcc -E的输出:

 int foo(){ _macro_var_foo++;} 

使用可变参数宏和x宏处理参数列表的版本:

 #define MY_MACRO(baz) _macro_var_##baz++; #define FUNC_DEF(ret_type,bar,...)\ ret_type bar(__VA_ARGS__)\ {\ MY_MACRO(bar)\ FUNC_CONTENTS\ } #define FUNC_CONTENTS\ printf("Do some stuff\n", s1, s2); FUNC_DEF(int, foo, char *s1, char *s2) #undef FUNC_CONTENT