2009-04-09 5 views
23

Je veux implémenter un traceur de fonction, qui tracerait combien de temps une fonction prend pour s'exécuter. Je suit classe pour le même: -Existe-t-il un moyen d'obtenir le nom d'une fonction dans une fonction C++?

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

Je veux savoir s'il y a un moyen d'obtenir le nom de la fonction à l'intérieur d'une fonction? Fondamentalement, je veux que les utilisateurs de ma classe créent simplement un objet identique. Ils ne peuvent pas passer le nom de la fonction.

Répondre

21

VC++ a

__FUNCTION__ for undecorated names 

et

__FUNCDNAME__ for decorated names 

Et vous pouvez écrire une macro qui s'allouer un objet et de transmettre la macro nom YELDING dans le constructeur. Smth comme

#define ALLOC_LOGGER FuncTracer ____tracer(__FUNCTION__); 
+0

Son fonctionnement dans VS2003 mais ne fonctionne pas dans VC6 – Canopus

+0

Qu'est-ce qui ne fonctionne pas? Les macros ne sont pas reconnues par le compilateur ou quoi? – sharptooth

+0

Oui. Lors de la compilation dans VC6, il indique __FUNCTION__ comme identifiant non déclaré. Ai-je manqué quelque chose ou n'est-ce pas supporté? – Canopus

46

C99 a __func__, mais pour C++ ce sera spécifique compilateur. Sur le plan positif, certaines des versions spécifiques au compilateur fournissent des informations de type supplémentaires, ce qui est particulièrement agréable lorsque vous tracez dans une fonction/classe modélisée.

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

bibliothèque Boost a défini macro BOOST_CURRENT_FUNCTION pour la plupart des compilateurs C++ en-tête boost/current_function.hpp. Si le compilateur est trop ancien pour supporter cela, le résultat sera "(inconnu)".

3

j'allais dire que je ne savais pas d'une telle chose, mais je vis les autres réponses ...

Il pourrait vous intéresser de savoir qu'un profileur d'exécution (comme gprof) fait exactement ce que vous Demandez-vous - il suit le temps passé à exécuter chaque fonction. Un profileur fonctionne essentiellement en enregistrant le pointeur d'instruction (IP), l'adresse de l'instruction en cours d'exécution, toutes les 10 ms environ. Une fois le programme exécuté, vous appelez un postprocesseur qui examine la liste des adresses IP et du programme et convertit ces adresses en noms de fonctions. Donc, je suggère d'utiliser simplement le pointeur d'instruction, plutôt que le nom de la fonction, à la fois parce qu'il est plus facile de coder et parce qu'il est plus efficace de travailler avec un seul nombre qu'avec une chaîne.

+1

Notez que pour ce faire, vous devez également enregistrer les adresses de chargement d'image de l'exécutable/des bibliothèques, sinon vous risquez de ne pas pouvoir interpréter correctement les adresses enregistrées. En outre, le support du compilateur pour les profileurs personnalisés (par exemple _penter/_pexit dans MSVC) peut être une alternative à l'échantillonnage périodique. – bk1e

Questions connexes