呼叫者功能的打印名称

时间:2019-11-26 11:09:36

标签: c linux macros c89

我发现__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)传递一个参数,我期望的是类似的宏或函数来检索调用者函数的名称。

4 个答案:

答案 0 :(得分:7)

没有从调用堆栈中获取名称的标准方法,并且如果调试信息被剥夺或以其他方式不可用,则根本不可能获得名称。

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

#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__

答案 1 :(得分: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;
}

答案 2 :(得分:1)

否,它不可用,也不可能。

因为像 @IBAction func doneButton(_ sender: Any) { let isLinkAValid = linkA.isEmpty ? true : linkA.isValidURL let isLinkBValid = linkB.isEmpty ? true : linkB.isValidURL let linkAText = linkA.isEmpty ? "No Link A" : linkATextField.text! let linkBText = linkB.isEmpty ? "No Link B" : linkBTextField.text! if isLinkAValid && isLinkBValid { saveData(strLinkA: linkAText, strLinkB: linkBText) } else { showErrorAlert() } } 这样的宏的值是在预处理阶段计算出来的,而在该阶段则无法执行任何操作。

答案 3 :(得分:1)

  

我不想将另一个参数传递给函数[...],我希望是类似的宏或函数来检索调用方函数的名称。

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

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