Есть ли способ получить имя функции внутри функции С++?
Я хочу реализовать функцию tracer, которая будет отслеживать, сколько времени функция выполняет для выполнения. У меня есть следующий класс для того же: -
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.
*/
}
Я хочу знать, есть ли способ получить имя функции изнутри функции? В основном я хочу, чтобы пользователи моего класса просто создавали объект одинаково. Они не могут передавать имя функции.
Ответы
Ответ 1
VС++ имеет
__FUNCTION__ for undecorated names
и
__FUNCDNAME__ for decorated names
И вы можете написать макрос, который сам выделит объект и передаст макрос с именем-указателем внутри конструктора. Smth нравится
#define ALLOC_LOGGER FuncTracer ____tracer( __FUNCTION__ );
Ответ 2
C99 имеет __func__
, но для С++ это будет специфичным для компилятора. С другой стороны, некоторые версии, относящиеся к компилятору, предоставляют дополнительную информацию о типе, что особенно приятно, когда вы отслеживаете внутри templatized function/class.
- MSVC:
__FUNCTION__
, __FUNCDNAME__
, __FUNCSIG__
- GCC:
__func__
, __FUNCTION__
, __PRETTY_FUNCTION__
Библиотека Boost определила макрос BOOST_CURRENT_FUNCTION
для большинства компиляторов С++ в заголовке boost/current_function.hpp. Если компилятор слишком стар для поддержки этого, результат будет "(неизвестно)".
Ответ 3
Я собирался сказать, что я не знал ничего подобного, но потом увидел другие ответы...
Вам может быть интересно узнать, что профилировщик выполнения (например, gprof
) выполняет именно то, о чем вы просите, - он отслеживает количество времени, затрачиваемого на выполнение каждой функции. Профайлер в основном работает, записывая указатель инструкции (IP), адрес исполняемой команды, каждые 10 мс или около того. После запуска программы вы вызываете постпроцессор, который проверяет список IP-адресов и программу и преобразует эти адреса в имена функций. Поэтому я бы предложил просто использовать указатель инструкций, а не имя функции, потому что он легче кодировать и потому что он более эффективен для работы с одним номером, чем со строкой.