Есть ли способ получить имя функции внутри функции C ++? - PullRequest
25 голосов
/ 09 апреля 2009

Я хочу реализовать трассировщик функций, который бы отслеживал, сколько времени занимает выполнение функции. У меня есть следующий класс для того же: -

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.
     */
}

Я хочу знать, есть ли способ получить имя функции изнутри функции? По сути, я хочу, чтобы пользователи моего класса просто создавали один и тот же объект. Они могут не передавать имя функции.

Ответы [ 3 ]

51 голосов
/ 09 апреля 2009

C99 имеет __func__, но для C ++ это будет зависеть от компилятора. С другой стороны, некоторые специфичные для компилятора версии предоставляют дополнительную информацию о типе, что особенно удобно при трассировке внутри шаблонизированной функции / класса.

  • MSVC : __FUNCTION__, __FUNCDNAME__, __FUNCSIG__
  • GCC : __func__, __FUNCTION__, __PRETTY_FUNCTION__

В библиотеке Boost определен макрос BOOST_CURRENT_FUNCTION для большинства компиляторов C ++ в заголовке boost / current_function.hpp . Если компилятор слишком стар, чтобы поддерживать это, результатом будет «(неизвестно)».

21 голосов
/ 09 апреля 2009

VC ++ имеет

__FUNCTION__ for undecorated names

и

__FUNCDNAME__ for decorated names

И вы можете написать макрос, который сам выделит объект и передаст макрос, вызывающий имя, внутри конструктора. Что-то вроде

#define ALLOC_LOGGER FuncTracer ____tracer( __FUNCTION__ );
3 голосов
/ 09 апреля 2009

Я собирался сказать, что ничего такого не знал, но потом увидел другие ответы ...

Возможно, вам будет интересно узнать, что профилировщик выполнения (например, gprof) делает именно то, о чем вы спрашиваете - он отслеживает количество времени, потраченное на выполнение каждой функции. Профилировщик в основном работает путем записи указателя инструкций (IP), адреса выполняемой в данный момент инструкции каждые 10 мс или около того. После завершения работы программы вы вызываете постпроцессор, который проверяет список IP-адресов и программы и преобразует эти адреса в имена функций. Поэтому я бы предложил использовать только указатель инструкций, а не имя функции, потому что это проще для кодирования и потому, что эффективнее работать с одним числом, чем со строкой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...