GCC _; func__;的计算结果为空字符串

GCC _; func__;的计算结果为空字符串,c,gcc,c-preprocessor,string-literals,C,Gcc,C Preprocessor,String Literals,考虑到我正在从事的项目中的以下代码: /* Pre-definitions in a pre-definitions file to be included in the project */ #ifdef WIN32 #define __FUNCNAME__ __FUNCTION__ #else #define __FUNCNAME__ __func__ #endif /* My definitions */ #define MAC() \ MAC1() #define M

考虑到我正在从事的项目中的以下代码:

/* Pre-definitions in a pre-definitions file to be included in the project */
#ifdef  WIN32
#define __FUNCNAME__ __FUNCTION__
#else
#define __FUNCNAME__ __func__  
#endif

/* My definitions */
#define MAC() \
     MAC1()

#define MAC1() \
     myPrintFunction(__FUNCNAME__)

/* My print function */
void myPrintFunction(const char * functionName)
{
     printf("\n func name: %s \n",functionName);
}

/* Macro usage example function */
void myFunction()
{
     if (some_condition)
     {
         MAC();
     }
}
函数名显示为空字符串。 知道为什么吗?我该怎么解决

使用GCC编译器在Linux机器上编译和测试的代码。

使用现成的函数。自C99以来,它一直是C标准的一部分。更改编译器设置以至少使用该标准

请注意_ufunc_uu不是一个宏,而是一个预定义的标识符,其形式如下:在函数体中的任何位置写入它与在该点使用它完全等效,首先写入

静态常量char _func _[]=函数名

就在函数体的开始括号之后

在形式上,当前代码的行为是未定义的。任何包含两个连续下划线的符号都由系统保留。包括宏名、函数名和变量名。

使用现成的函数名。自C99以来,它一直是C标准的一部分。更改编译器设置以至少使用该标准

请注意_ufunc_uu不是一个宏,而是一个预定义的标识符,其形式如下:在函数体中的任何位置写入它与在该点使用它完全等效,首先写入

静态常量char _func _[]=函数名

就在函数体的开始括号之后


在形式上,当前代码的行为是未定义的。任何包含两个连续下划线的符号都由系统保留。这包括宏名称、函数名称和变量名称。

在添加必要的include和main之后,您的代码将给出预期的结果:

#include <stdio.h>

#ifdef  WIN32
#define __FUNCNAME__ __FUNCTION__
#else
#define __FUNCNAME__ __func__  
#endif

/* My definitions */
#define MAC() \
     MAC1()

#define MAC1() \
     myPrintFunction(__FUNCNAME__)

void myPrintFunction(const char * functionName)
{
     printf("\n func name: %s \n",functionName);
}

int main()
{
    MAC();
}
我使用gcc-std=c11-Wall-Wextra-Wwrite strings-Wno圆括号-Wpedantic-Warray边界编译了它,没有任何警告

您应该发布一个完整但最少的实际编译的示例,以及您使用的编译器标志,因为一定有不同的东西来解释您描述的症状


另外,在将语句编写为宏时,您可能会发现使用do{…}while 0习惯用法有助于避免意外的扩展更改控制流。

在我添加必要的include和main之后,您的代码给出了预期的结果:

#include <stdio.h>

#ifdef  WIN32
#define __FUNCNAME__ __FUNCTION__
#else
#define __FUNCNAME__ __func__  
#endif

/* My definitions */
#define MAC() \
     MAC1()

#define MAC1() \
     myPrintFunction(__FUNCNAME__)

void myPrintFunction(const char * functionName)
{
     printf("\n func name: %s \n",functionName);
}

int main()
{
    MAC();
}
我使用gcc-std=c11-Wall-Wextra-Wwrite strings-Wno圆括号-Wpedantic-Warray边界编译了它,没有任何警告

您应该发布一个完整但最少的实际编译的示例,以及您使用的编译器标志,因为一定有不同的东西来解释您描述的症状


此外,在将语句编写为宏时,您可能会发现使用do{…}while 0习惯用法有助于避免意外的扩展更改控制流。

您确定某些条件为真吗?无主?请发一封邮件。是的,我确定。我可以看到\n func名称:\n并且我正在使用调试器调试此代码,并且该代码正在执行。1如果在源代码中用myPrintFunction\uuuFuncName\uuuuuuuuu替换MAC,会发生什么情况?2您是否真的有如图所示编写的MAC和MAC1的定义,在名称和预期定义之间有一个换行符,并且在定义行末尾没有反斜杠?可能是这样的情况,函数在第一次通过时展开…您确定某个条件为真吗?没有main?请发一封邮件。是的,我确定。我可以看到\n func名称:\n并且我正在使用调试器调试此代码,并且该代码正在执行。1如果在源代码中用myPrintFunction\uuuFuncName\uuuuuuuuu替换MAC,会发生什么情况?2您是否真的有如图所示编写的MAC和MAC1的定义,在名称和预期定义之间有一个换行符,定义行末尾没有反斜杠?可能是在第一次运行时扩展了_func__…我想你的意思是说任何包含两个连续下划线的宏名称…抱歉,我的意思是更强大:宏名称,函数名称,和变量name@TobySpeight:那么,如果我将一个局部变量命名为int u func_u?@Bathsheba:和类型名、成员名和struct/union/enum标记:--我认为涵盖所有内容的术语都是identifier.@yg这样做你会很生气的。前导下划线是保留的。我想你的意思是说任何包含两个连续下划线的宏名……对不起,我的意思是更强大:宏名、函数名和变量name@TobySpeight:那么,如果我将一个局部变量命名为int _func_Ø?@Bathsheba:并键入名称,成员名和struct/union/enum标记:--我认为涵盖所有内容的术语都是identifier.@AndyG如果这样做,你会很生气的。前导下划线是保留的。