【问题标题】:Print name of caller function打印调用函数的名称
【发布时间】:2019-11-26 11:09:36
【问题描述】:

我发现__FUNCTION__ 宏会给出当前正在执行的函数的名称,但是是否有任何宏可用于打印父函数的名称(调用当前正在运行的函数的函数)?

void print_error_message(const char *msg)
{
    printf("%s : %s\n",__FUNCTION__,msg);
}

int main()
{
    print_error_message("failed to connect");
    return 0;
}

上面的程序会给出输出:

print_error_message : failed to connect

但我真正需要的是

main : failed to connect

因为main() 调用了print_error_message()

我不想再向函数print_error_message() 传递一个参数,比如print_error_message(__FUNCTION__, msg),我期望的是一个类似的宏或函数来检索调用函数的名称。

【问题讨论】:

标签: c linux macros c89


【解决方案1】:

没有从调用堆栈中获取名称的标准方法,如果调试信息被剥离或不可用,则根本无法获取名称。

作为一种简单的解决方法,您可以使用宏:

#define print_error_message(msg) actual_print_error_message(__FUNCTION__, (msg))

void actual_print_error_message(const char *func, const char *msg)
{
    printf("%s : %s\n",func,msg);
}

注意__FUNCTION__ 不是标准C,它是一个扩展。为了符合标准,请使用 C99 特殊预定义变量 __func__

【讨论】:

    【解决方案2】:

    您可以让调用者将其函数名作为参数传递。例如:

    void print_error_message(const char *msg, const char *caller)
    {
        printf("%s : %s\n",caller,msg);
    }
    
    int main()
    {
        print_error_message("failed to connect", __FUNCTION__);
        return 0;
    }
    

    【讨论】:

      【解决方案3】:

      不,不可用,也不可能。

      因为像__FUNCTION__ 这样的宏的值是在预处理阶段计算的,而您想要做的事情在那个阶段是不可能的。

      【讨论】:

      • 但我希望有任何库函数可以完成这项工作
      • 其实预处理器并不知道函数是什么。所以__FUNCTION__ 不被预处理器处理。
      • @JonathanLeffler ?那么什么阶段将其转换为函数名?
      • 正确的编译器。它知道什么是函数。
      【解决方案4】:

      我不想再向函数传递一个参数 [...] 我期待的是一个类似的宏或函数来检索调用函数的名称。

      这不存在,至少不是 C 标准的一部分。

      在 Linux 上,GCC 提供了拉取backtrace 信息的能力。也许这对你有帮助。

      【讨论】:

        猜你喜欢
        • 2019-01-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-10-01
        • 1970-01-01
        • 2018-09-28
        • 2017-12-05
        相关资源
        最近更新 更多