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如果这样做,你会很生气的。前导下划线是保留的。