2017-07-04 4 views
3

Quelle est la raison de la g ++ abi::__cxa_demangle fonction de ne pas retourner la valeur de retour pour les fonctions de membres?Type de retour dans le nom de la fonction membre demangled

Voici un exemple concret de ce comportement

#include <execinfo.h> 
#include <cxxabi.h> 
#include <iostream> 

struct Foo { 
    void operator()() const 
    { 
     constexpr int buf_size = 100; 
     static void *buffer[buf_size]; 
     int nptrs = backtrace(buffer, buf_size); 
     char **strings = backtrace_symbols(buffer, nptrs); 
     for(int i = 0; i < nptrs; ++i) { 

      auto str = std::string(strings[i]); 
      auto first = str.find_last_of('(') + 1; 
      auto last = str.find_last_of(')'); 
      auto mas = str.find_last_of('+'); 

      int status; 
      char* result = abi::__cxa_demangle(str.substr(first, mas-first).c_str(), nullptr, nullptr, &status); 
      if (status == 0) std::cout << result << std::endl; 
     } 
    } 
}; 

int main() { 
    Foo f; 
    f(); 
} 

et après la compilation avec g++ foo.cpp -std=c++11 -rdynamic la sortie est Foo::operator()() const

Est-il possible d'obtenir un comportement cohérent, c'est, obtenir aussi renvoie la valeur pour les fonctions membres?

Répondre

3

Mangling/demangling des noms de fonction est au-delà de la portée de la norme C++. Il est de la responsabilité du compilateur et de la nécessité de manœuvrer les fonctions de telle sorte que deux fonctions différentes aient des représentations mutilées différentes (symboles). Dans le même temps, comme la déclaration de deux fonctions qui diffèrent uniquement par leur type de retour est interdite par la norme, le compilateur n'a pas besoin de modifier le type de retour, car il n'y aura aucun avantage.

Ce que vous voyez est juste une conséquence du compilateur raisonnablement être paresseux.

Aussi, voici un rextester avec un exemple plus complet (y compris une fonction globale dans le backtrace).

+0

Bien sûr, mais il demangle le type de retour pour les noms de fonctions non-membres. – Lezkus

+0

@Lezkus Non, ce n'est pas pour moi. Juste vérifié avec gcc 4.8.4 en ajoutant 'int bar (const Foo & foo) {foo(); renvoie 0; } ', et l'appel de' main' - l'entrée pour 'bar' n'a pas non plus le type de retour. – iehrlich

+0

@Lezkus voir le lien dans la mise à jour. – iehrlich