C语言 我们如何知道调用者函数的名称?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16100090/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can we know the caller function's name?
提问by Tom Xue
In the C language, __FUNCTION__can be used to get the currentfunction's name.
But if I define a function named a() and it is called in b(), like below:
在 C 语言中,__FUNCTION__可用于获取当前函数的名称。但是如果我定义了一个名为 a() 的函数并在 b() 中调用它,如下所示:
b()
{
a();
}
Now, in the source code, there are lots of functions like b() that call a(), e.g. c(), d(), e()...
现在,在源代码中,有很多像 b() 这样调用 a() 的函数,例如 c()、d()、e()...
Is it possible, within a(), to add some code to detect the name of the function that called a()?
是否可以在 a() 中添加一些代码来检测调用 a() 的函数的名称?
Further:
更远:
- Sorry for the misleading typo. I have corrected it.
- I am trying to find out which function calls a() for debugging purposes. I don't know how you do when in the same situation?
- And my code is under vxWorks, but I am not sure whether it is related to C99 or something else.
- 对不起,误导性的错字。我已经改正了。
- 我试图找出哪个函数调用 a() 以进行调试。不知道你遇到同样的情况怎么办?
- 我的代码在vxWorks下,但我不确定它是否与C99或其他相关。
回答by Didier Trosset
There's nothing you can do only in a.
没有什么是你只能在 a 中做的。
However, with a simple standard macro trick, you can achieve what you want, IIUC showing the name of the caller.
然而,通过一个简单的标准宏技巧,你可以实现你想要的,IIUC 显示调用者的名字。
void a()
{
/* Your code */
}
void a_special( char const * caller_name )
{
printf( "a was called from %s", caller_name );
a();
}
#define a() a_special(__func__)
void b()
{
a();
}
回答by alk
Try this:
尝试这个:
void a(<all param declarations to a()>);
#ifdef DEBUG
# define a(<all params to a()>) a_debug(<all params a()>, __FUNCTION__)
void a_debug(<all params to a()>, const char * calledby);
#endif
void b(void)
{
a(<all values to a()>);
}
#ifdef DEBUG
# undef a
#endif
void a(<all param declarations to a()>)
{
printf("'%s' called\n", __FUNCTION__);
}
#ifdef DEBUG
void a_debug(<all param declarations to a()>, const char * calledby)
{
printf("'%s' calledby '%s'", __FUNCTION__, calledby);
a(<all params to a()>);
}
#endif
If for example <all param declarations to a()>is int i, double d, void * pthen <all params to a()>is i, d, p.
例如,如果<all param declarations to a()>是,int i, double d, void * p则<all params to a()>是i, d, p。
Or (less evil ;->> - but more code modding, as each call to a() needs to be touched):
或者(不那么邪恶;->> - 但更多的代码修改,因为每次调用 a() 都需要被触及):
void a((<all params of normal a()>
#ifdef DEBUG
, const char * calledby
#endif
);
void a((<all params of normal a()>
#ifdef DEBUG
, const char * calledby
#endif
)
{
#ifdef DEBUG
printf("'%s' calledby '%s', __FUNCTION__, calledby);
#endif
...
}
...
void b(void)
{
a(<all params of normal a()>
#ifdef DEBUG
, __FUNC__
#endif
);
}
__FUNCTION__is available on GCC (at least?), if using a different C99 compiler replace it with __func__.
__FUNCTION__在 GCC 上可用(至少?),如果使用不同的 C99 编译器将其替换为__func__.
回答by Bechir
回答by Vicky
You can do it with a gcc builtin.
您可以使用内置的 gcc 来完成。
The following way should print the immediate caller of a function a().
以下方式应该打印函数 a() 的直接调用者。
Example:
例子:
a() {
printf ("Caller name: %pS\n", __builtin_return_address(0));
}
回答by Dmitry Sazonov
If your platform is Windows, you may use this: walking the callstack
如果你的平台是 Windows,你可以使用这个:walk the callstack
回答by Raunak
Refer: https://www.gnu.org/software/libc/manual/html_node/Backtraces.html
参考:https: //www.gnu.org/software/libc/manual/html_node/Backtraces.html
A backtrace is a list of the function calls that are currently active in a thread. The usual way to inspect a backtrace of a program is to use an external debugger such as gdb. However, sometimes it is useful to obtain a backtrace programmatically from within a program, e.g., for the purposes of logging or diagnostics.
The header file execinfo.h declares three functions that obtain and manipulate backtraces of the current thread.
回溯是线程中当前处于活动状态的函数调用的列表。检查程序回溯的常用方法是使用外部调试器,例如 gdb。然而,有时从程序中以编程方式获取回溯是有用的,例如,出于日志记录或诊断的目的。
头文件 execinfo.h 声明了三个获取和操作当前线程回溯的函数。
回答by Joe
If you're only after knowing where you were for logging/debug purposes you can use a macro to avoid __func__giving the name of your logging/debug function but of the function calling it.
如果您只是在知道您在哪里进行日志记录/调试之后,您可以使用宏来避免__func__提供您的日志记录/调试函数的名称,而是提供调用它的函数的名称。
Being in a macro will not result in a change to __func__but will "feel" like using a function.
在宏中不会导致更改,__func__但会“感觉”像使用函数。
e.g.
例如
#define LOG(s, data...) log("%s: "s, __function__, ## data)
回答by Rüppell's Vulture
You can tag each function that calls a()with an integer identifier which is passed to a()as a parameter and then use a switch-caseconstruct in a()to tell which function has invoked a().A printf()would tell which function invoked a()depending on the integer identifier value if you use that as an argument to a switch-case construct in a()
您可以使用整数标识符标记调用a() 的每个函数,该标识符作为参数传递给a(),然后在a() 中使用switch-case构造来判断哪个函数调用 了 a().A printf()如果您将其用作a() 中switch-case 构造的参数,将根据整数标识符值判断 调用a() 的函数
#include<stdio.h>
void a(int);
void b();
void c();
void d();
int main(void)
{
b();
c();
d();
}
void b()
{
int x=1;
a(x);
}
void c()
{
int x=2;
a(x);
}
void d()
{
int x=3;
a(x);
}
void a(int x)
{
switch(x)
{
case 1:
printf("b called me\n");
break;
case 2:
printf("c called me\n");
break;
case 3:
printf("d called me\n");
}
}
回答by user2682078
#include <stdio.h>
#include <stdlib.h>
#define FUNCTION_NAME(FUNCTION) printf("FUNCTION=%s \r\n", #FUNCTION);
#define FUNCTION_NAME( FUNCTION) printf(" FUNCTION=%s \r\n", # FUNCTION);
int a() {
printf("A function call");
}
int b() {
printf("B function call");
}
int main(){
FUNCTION_NAME(a);
FUNCTION_NAME(b);
return 0;
}
}
回答by Koala Bear
If the function in question is in a different c file, you can do
如果有问题的函数在不同的 c 文件中,你可以这样做
#define name_of_function(...) \
printf("Function %s is parent\n", __FUNCTION__); \
name_of_function(__VA_ARGS__);
And at the top of the c file it lives in
并且在它所在的 c 文件的顶部
#ifdef name_of_function
#undef name_of_function
#endif
If they're in the same file, you can wrap the function definition in the second macro, then redefine the first macro at the end. It's not terribly extensible because you can't generate new defines from other defines, but if you're trying to track down parents for a particular function it works without any nonsense.
如果它们在同一个文件中,您可以将函数定义包装在第二个宏中,然后在最后重新定义第一个宏。它不是非常可扩展,因为您无法从其他定义中生成新定义,但是如果您试图为特定功能追踪父项,它可以毫无意义地工作。

