我想实现一个函数跟踪器,它将跟踪一个函数执行的时间。我有以下课程: -
class FuncTracer
{
public:
FuncTracer(LPCTSTR strFuncName_in)
{
m_strFuncName[0] = _T('\0');
if( strFuncName_in ||
_T('\0') != strFuncName_in[0])
{
_tcscpy(m_strFuncName,strFuncName_in);
TCHAR strLog[MAX_PATH];
_stprintf(strLog,_T("Entering Func:- <%s>"),m_strFuncName);
LOG(strLog)
m_dwEnterTime = GetTickCount();
}
}
~FuncTracer()
{
TCHAR strLog[MAX_PATH];
_stprintf(strLog,_T("Leaving Func:- <%s>, Time inside the func <%d> ms"),m_strFuncName, GetTickCount()-m_dwEnterTime);
LOG(strLog)
}
private:
TCHAR m_strFuncName[MAX_PATH];
DWORD m_dwEnterTime;
};
void TestClass::TestFunction()
{
// I want to avoid writing the function name maually..
// Is there any macro (__LINE__)or some other way to
// get the function name inside a function ??
FuncTracer(_T("TestClass::TestFunction"));
/*
* Rest of the function code.
*/
}
我想知道是否有办法从函数内部获取函数的名称?基本上我希望我班级的用户只需创建一个相同的对象。它们可能无法传递函数名称。
答案 0 :(得分:51)
C99有__func__
,但对于C ++,这将是编译器特定的。从好的方面来说,一些特定于编译器的版本提供了额外的类型信息,当你在一个模板化的函数/类中进行跟踪时,这个信息特别好。
Boost库为标题boost/current_function.hpp中的大多数C ++编译器定义了宏BOOST_CURRENT_FUNCTION
。如果编译器太旧而无法支持,那么结果将是“(未知)”。
答案 1 :(得分:21)
VC ++有
__FUNCTION__ for undecorated names
和
__FUNCDNAME__ for decorated names
你可以编写一个宏,它本身会分配一个对象并在构造函数中传递name-yelding宏。像Smth一样
#define ALLOC_LOGGER FuncTracer ____tracer( __FUNCTION__ );
答案 2 :(得分:6)
C ++ 20 std::source_location::function_name
这基本上可以满足您的需求。
https://en.cppreference.com/w/cpp/utility/source_location的声明用法类似于:
#include <iostream>
#include <string_view>
#include <source_location>
void log(std::string_view message,
const std::source_location& location std::source_location::current()
) {
std::cout << "info:"
<< location.file_name() << ":"
<< location.line() << ":"
<< location.function_name() << " "
<< message << '\n';
}
int main() {
log("Hello world!");
}
可能的输出:
info:main.cpp:16:main Hello world!
因此请注意呼叫如何保留呼叫者信息。
我已经在What's the difference between __PRETTY_FUNCTION__, __FUNCTION__, __func__?
上详细介绍了相关标准。答案 3 :(得分:3)
我打算说我不知道任何这样的事情,但后来我看到了其他答案......
您可能会感兴趣的是,执行探查器(如gprof
)完全符合您的要求 - 它会跟踪执行每个功能所花费的时间。分析器基本上通过记录指令指针(IP)(当前正在执行的指令的地址)每10ms左右来工作。程序运行完毕后,调用后处理器检查IP列表和程序,并将这些地址转换为函数名。所以我建议只使用指令指针,而不是函数名称,因为它更容易编码,因为使用单个数字比使用字符串更有效。