我发现__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)
传递一个参数,我期望的是类似的宏或函数来检索调用者函数的名称。
答案 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信息的功能。也许这对您有帮助。