在C中获取调用函数的名称(不使用预处理器)

我想知道是否有办法在C中找到称为当前函数(在运行时)的函数。

我知道你可以在gcc中使用__FUNCTION__ ,但有没有办法不使用C预处理器?

可能不是。

干杯

不,没有。 C不是一种特别内省的语言 – 诸如函数名称(或调用堆栈的部分)之类的东西在运行时不能以任何理智的方式提供。

如果由于某种原因,您正在寻找大量工作而没有什么好处,那么您可以使用调试符号构建程序,并且可以编写堆栈遍历和调试符号查找代码。 那么你或许可以在飞行中找到它。 但要小心,因为如果你涉及到任何C ++,你将在调试信息中看到的符号将用类型信息进行修饰。

你已经标记了这个postgcc,所以相关的细节是可用的,但这属于’不推荐’和’不保证在编译器版本之间相同’的区域。

假设你有一个函数f(),你想知道调用者。

将该函数重命名为f_func()并定义一个宏f(),它打印__func__然后调用f_func()。 例:

 void f_func() { do something; } #define f() \ do { \ printf("f called from %s\n", __func__); \ f_func(); \ } while (0) void a() { f(); } void b() { f(); } int main(int argc, char **argv) { a(); b(); return(0); } 

无法在运行时获取函数名称。 唯一的方法是预处理器,但它的function非常有限。 如果您有可用的调试信息,您可以遍历堆栈并从调试信息中获取函数名称。 然而,这既不是强大的也不是便携式的解决方案。

有几个GNU函数允许您从backtrace – backtrace()backtrace_symbols()获取函数地址和名称,但是您需要使用-rdynamic标志编译二进制文件

没有

最简洁的答案是不

但是使用预处理器可以像这样完成

在C中获取调用函数的名称(使用预处理器)

假设您有一个函数f(),您只想从中调用调用程序以进行调试。

将该函数重命名为f_func()并定义一个宏f(),它调用f的版本打印func ,然后在定义DEBUG时调用f_func()。

在最终版本中,通过调用实函数f_func()来删除信息

 #ifdef DEBUG #define f(a,b,c) f_debug(a,b,c, __func__) #else #define f(a,b,c) f_func(a,b,c) #endif bool f_func(int par1, int par2, int par3) { do_somthing(); } bool f_debug((int par1, int par2, int par3, const char calling_func_name[]) { printf("f called from %s\n", calling_func_name); f_func(); } void a() { f(); } void b() { f(); } int main(int argc, char **argv) { a(); b(); return(0); } 

结果是:

当DEBUG被定义时

f来自a
f来自b

使用__func__标识符。 标准 (第6.4.2.2节) 要求它出于正确的目的:

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

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

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

正如Steve Jessop在评论中指出的那样,这不是预处理器的一部分,而是编译器的固有部分。

可能有办法通过遍历堆栈并查看调试符号来查找此名称。 可爱,但疯了。