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
How to find the name of the current function at runtime?
提问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_FUNCTION
is 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 DaClown
__FUNCTION__
or __FUNC__
or __PRETTY_FUNCTION__
__FUNCTION__
或__FUNC__
或__PRETTY_FUNCTION__
http://msdn.microsoft.com/en-us/library/b0084kay(VS.80).aspxhttp://gcc.gnu.org/onlinedocs/gcc/Function-Names.html
http://msdn.microsoft.com/en-us/library/b0084kay(VS.80).aspx http://gcc.gnu.org/onlinedocs/gcc/Function-Names.html
回答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();