C++ 如何在运行时找到当前函数的名称?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/679021/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 16:41:53  来源:igfitidea点击:

How to find the name of the current function at runtime?

c++functionassert

提问by demoncodemonkey

After years of using the big ugly MFC ASSERT macro, I have finally decided to ditch it and create the ultimate ASSERT macro.

经过多年使用丑陋的 MFC ASSERT 宏,我终于决定放弃它并创建最终的 ASSERT 宏。

I am fine with getting the file and line number, and even the expression that failed. I can display a messagebox with these in, and Abort/Retry/Cancel buttons.

我可以获取文件和行号,甚至是失败的表达式。我可以显示带有这些内容的消息框和中止/重试/取消按钮。

And when I press Retry the VS debugger jumps to the line containing the ASSERT call (as opposed to the disassembly somewhere like some other ASSERT functions). So it's all pretty much working.

当我按下 Retry 时,VS 调试器会跳转到包含 ASSERT 调用的行(而不是像其他一些 ASSERT 函数那样在某处进行反汇编)。所以这一切都非常有效。

But what would be really cool would be to display the name of the function that failed.

但是真正酷的是显示失败的函数的名称

Then I can decide whether to debug it without trying to guess what function it's in from the filename.

然后我可以决定是否调试它,而无需尝试从文件名中猜测它的功能。

e.g. if I have the following function:

例如,如果我有以下功能:

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
   ASSERT(lpCreateStruct->cx > 0);
   ...
}

Then when the ASSERT fires, the messagebox would show something like:

然后当 ASSERT 触发时,消息框将显示如下内容:

Function = CMainFrame::OnCreate

So, what's the simplest way of finding out the current function name, at runtime?

那么,在运行时找出当前函数名称的最简单方法是什么?

It should not use MFC or the .NET framework, even though I do use both of these.
It should be as portable as possible.

它不应该使用 MFC 或 .NET 框架,即使我确实使用了这两者。
它应该尽可能便携。

回答by Assaf Lavie

Your macro can contain the __FUNCTION__macro. Make no mistake, the function name will beinserted into the expanded code at compile time, but it will be the correct function name for each call to your macro. So it "seems like" it happens in run-time ;)

您的宏可以包含__FUNCTION__宏。毫无疑问,函数名会被插入到扩展代码的编译时间,但它会为每次调用宏正确的函数名。所以它“似乎”发生在运行时;)

e.g.

例如

#define THROW_IF(val) if (val) throw "error in " __FUNCTION__

int foo()
{
    int a = 0;
    THROW_IF(a > 0); // will throw "error in foo()"
}

回答by YenTheFirst

The C++ preprocessor macro __FUNCTION__gives the name of the function.

C++ 预处理器宏__FUNCTION__给出了函数的名称。

Note that if you use this, it's not reallygetting the filename, line number, or function name at runtime. Macros are expanded by the preprocessor, and compiled in.

请注意,如果您使用它,它不会在运行时真正获得文件名、行号或函数名。宏由预处理器扩展并编译。

The __FUNCTION__macro, like __LINE__, and __FILE__, is part of the language standard, and is portable.

__FUNCTION__宏象__LINE__,并且__FILE__,是语言标准的一部分,并且是便携式的。

Example program:

示例程序:

#include <iostream>
#using namespace std;

void function1()
{
        cout << "my function name is: " << __FUNCTION__ << "\n";
}
int main()
{
        cout << "my function name is: " << __FUNCTION__ << "\n";
        function1();
        return 0;
}

output:

输出:

my function name is: main
my function name is: function1

回答by fizzer

There's no standard solution. However, BOOST_CURRENT_FUNCTIONis portable for all practical purposes. The header does not not depend on any of the other Boost headers, so can be used standalone if the overhead of the whole library is unacceptable.

没有标准的解决方案。但是,BOOST_CURRENT_FUNCTION对于所有实际目的来说都是可移植的。头文件不依赖于任何其他 Boost 头文件,因此如果整个库的开销无法接受,可以单独使用。

回答by Matt

In GCC you can use the __PRETTY_FUNCTION__macro.
Microsoft also have an equivalent __func__macro although I don't have that available to try.

在 GCC 中,您可以使用__PRETTY_FUNCTION__宏。
Microsoft 也有一个等效的__func__宏,尽管我没有可以尝试的宏。

e.g. to use __PRETTY_FUNCTION__putting something like this at the beginning of your functions and you'll get a complete trace

例如,__PRETTY_FUNCTION__在函数的开头使用这样的内容,您将获得完整的跟踪

void foo(char* bar){
  cout << __PRETTY_FUNCTION__ << std::endl
}

which will output

这将输出

void foo(char* bar)

You also have the __FILE__and __LINE__macros available under all standard c/c++ compilers if you want to output even more information.

如果您想输出更多信息,您还可以在所有标准 c/c++ 编译器下使用__FILE____LINE__宏。

In practice I have a special debugging class which I use instead of cout. By defining appropriate environment variables I can get a full program trace. You could do something similar. These macros are incredibly handy and it's really great to be able to turn on selective debugging like this in the field.

在实践中,我有一个特殊的调试类,我用它来代替 cout。通过定义适当的环境变量,我可以获得完整的程序跟踪。你可以做类似的事情。这些宏非常方便,能够在现场打开这样的选择性调试真的很棒。

EDIT: apparently __func__is part of the standard? didn't know that. Unfortunately, it only gives the function name and not the parameters as well. I do like gcc's __PRETTY_FUNC__but it's not portable to other compilers.

编辑:显然__func__是标准的一部分?不知道。不幸的是,它只给出了函数名,而没有给出参数。我确实喜欢 gcc,__PRETTY_FUNC__但它不能移植到其他编译器。

GCC also supports __FUNCTION__.

GCC 还支持__FUNCTION__.

回答by Andrew Grant

You can use the __FUNCTION__macrowhich at compile time will be expanded to the name of the function.

您可以使用在编译时将扩展为函数名称的__FUNCTION__

Here's an example of how to use it in an assert macro.

这是如何在断言宏中使用它的示例。

#define ASSERT(cond) \
    do { if (!(cond)) \
    MessageBoxFunction("Failed: %s in Function %s", #cond, __FUNCTION__);\
    } while(0)

void MessageBoxFunction(const char* const msg,  ...)
{
    char szAssertMsg[2048];

    // format args
    va_list vargs;
    va_start(vargs, msg);
    vsprintf(szAssertMsg, msg, vargs);
    va_end(vargs);

    ::MessageBoxA(NULL, szAssertMsg, "Failed Assertion", MB_ICONERROR | MB_OK);
}

回答by Hosein Basafa

you can easily use func. it will take back you current function name at runtime which raised the exception.

您可以轻松使用func。它将在运行时取回您当前引发异常的函数名称。

usage:

用法:

cout << __func__ << ": " << e.what();