C 我们如何知道调用者函数';她叫什么名字?

C 我们如何知道调用者函数';她叫什么名字?,c,C,在C语言中,\uuuuu函数可用于获取当前函数的名称。 但是如果我定义了一个名为a()的函数,并在b()中调用它,如下所示: b() { a(); } 现在,在源代码中,有很多像b()这样的函数调用a(),例如c(),d(),e() 是否可以在a()中添加一些代码来检测调用a()的函数的名称 进一步: 对不起,有误导性的打字错误。我已经改正了 我试图找出哪个函数调用a()进行调试。我 不知道在同样的情况下你会怎么做 我的代码在vxWorks下,但我不确定它是否与C99相关 还有别的 您

在C语言中,
\uuuuu函数
可用于获取当前函数的名称。 但是如果我定义了一个名为a()的函数,并在b()中调用它,如下所示:

b()
{
    a();
}
现在,在源代码中,有很多像b()这样的函数调用a(),例如c(),d(),e()

是否可以在a()中添加一些代码来检测调用a()的函数的名称

进一步:

  • 对不起,有误导性的打字错误。我已经改正了
  • 我试图找出哪个函数调用a()进行调试。我 不知道在同样的情况下你会怎么做
  • 我的代码在vxWorks下,但我不确定它是否与C99相关 还有别的

  • 您可以使用传递给a()作为参数的整数标识符标记调用a()的每个函数,然后在a()中使用开关大小写构造来告诉哪个函数调用了a()。aprintf()将根据整型标识符值判断调用了哪个函数a(),如果您将该值用作a()中开关大小写构造的参数

    #包括
    无效a(int);
    无效b();
    无效c();
    无效d();
    内部主(空)
    {
    b();
    c();
    d();
    }
    无效b()
    {
    int x=1;
    a(x);
    }
    void c()
    {
    int x=2;
    a(x);
    }
    无效d()
    {
    int x=3;
    a(x);
    }
    无效a(整数x)
    {
    开关(x)
    {
    案例1:
    printf(“b称我\n”);
    打破
    案例2:
    printf(“c调用我\n”);
    打破
    案例3:
    printf(“d叫我\n”);
    }
    }
    
    试试这个:

    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
    


    如果使用不同的C99编译器将其替换为
    \uuuuuu func\uuuuu
    则GCC上提供了
    \uuuu函数\uuuuuu
    (至少?)您只能在a中执行任何操作

    然而,通过一个简单的标准宏技巧,您可以实现您想要的,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();
    }
    

    如果您只是在了解了日志记录/调试的位置之后,才可以使用宏来避免
    \uuuu func\uuu
    给出您的日志记录/调试函数的名称,而不是调用它的函数的名称

    处于宏中不会导致更改为
    \uuuu func\uuuu
    ,但会“感觉”像在使用函数

    e、 g


    如果您使用的是Linux系统,则可以使用
    backtrace()
    函数


    有关更多详细信息和代码示例,请参见

    如果您的平台是Windows,您可以使用以下内容:

    请参阅:

    回溯是当前活动的函数调用的列表 在一个线程中。检查程序回溯的常用方法是 使用外部调试器,如gdb。然而,有时它是有用的 以编程方式从程序内获取回溯,例如。, 用于记录或诊断

    头文件execinfo.h声明了三个函数,用于获取和 操纵当前线程的回溯


    }

    您可以使用gcc内置组件来完成

    下面的方法应该打印函数a()的直接调用方

    例如:

    a(){
    printf(“呼叫者名称:%pS\n”,内置返回地址(0));
    }
    
    如果所讨论的函数位于不同的c文件中,您可以执行以下操作

    #define name_of_function(...) \
        printf("Function %s is parent\n", __FUNCTION__); \
        name_of_function(__VA_ARGS__);
    
    在它所在的c文件的顶部

    #ifdef name_of_function
    #undef name_of_function
    #endif
    
    如果它们在同一个文件中,可以将函数定义包装到第二个宏中,然后在末尾重新定义第一个宏。 它的可扩展性不太好,因为您无法从其他定义生成新的定义,但如果您试图跟踪某个特定函数的父函数,它将毫无意义地工作


    不确定。但也许对你有帮助你为什么要这么做?它是为了调试吗?如果这只是为了调试,您可以将a定义为宏,这样使用
    \uuuuu func\uuuu
    将根据您的需要返回b。哪个编译器具有返回当前函数名称的函数?C标准中预见的标识符是
    \uu func\uu
    IIRC。您编写的是错误的<代码>\uuuu FUNC\uuu返回当前方法名AFAIK。要找到来电者,您必须查看stacktrace:d。我觉得这很糟糕,但这是一种很酷的方式,因为这是一种“解决方法”,而不是解决方案。如果你需要提供外部API-你的直接方式将毫无用处。@DmitrySazonov我回答了海报的要求。不是更多,不是更少。这是一个解决方案。它不是一个解决方案,因为你更改了函数签名。没关系,这只是我的意见;)或者,您可以将
    \uuuuu函数\uuuu
    传递到()。不需要开关,它可以处理新函数、更改的函数名等。当然,正如Dmitry Sazonov所说,添加该参数确实会更改函数的签名。Sry,但这并不能回答OP的问题。因为我们不知道他们为什么需要这样做,它可能会确认Joe,事实上,这正是我要搜索的,我必须将caller\u name变量声明为
    const char*caller\u name
    ,但它成功了!精度:
    \uuuuuu func\uuuu
    是C99标准的一部分,[…]
    \uuuuu FUNCTION\uuuu
    \uuuuu func\uuuu
    的另一个名称,用于向后兼容旧版本的GCC。(来源:)你能告诉我如何在函数声明中使用你的带省略号的例子吗
    void a(int a,char*fmt,…)
    如何将其包含在宏定义中?@mulg0r查看
    va_列表
    va_arg
    和相关信息。然而,我怀疑你能用省略号将这个技巧应用到一个函数上:它应该用
    va_list
    来编写,就像
    vprintf
    函数系列一样:-(@mulg0r使用它你可以实现你想要的(例如
    )(定义一个(…)一个特殊(\u函数,\u va_参数)
    ,对于一个函数
    void a_特殊(Cch-const *CalryNoNd,…){} /Cord>)它们在C中是从C99和C++开始的,因为C++ 11.这是打印返回地址(仍然有用),但不是函数名。在2020年底,Mac OS也可用。
    
    #define LOG(s, data...) log("%s: "s, __function__, ## data)
    
    #include <stdio.h>
    #include <stdlib.h>
    
    int a() {
      printf("A function call");
    }
    
    int b() {
      printf("B function call");
    }
    
    int main(){
    FUNCTION_NAME(a);
    FUNCTION_NAME(b);
    return 0;
    
    #define name_of_function(...) \
        printf("Function %s is parent\n", __FUNCTION__); \
        name_of_function(__VA_ARGS__);
    
    #ifdef name_of_function
    #undef name_of_function
    #endif