SORU
11 Kasım 2008, Salı


Std sonucu::type_info::Unmangling adı

Şu anda - diğer şeyler arasında - arama işlevi ile ilgili bilgileri yazdırmak için gereken bazı günlük kod üzerinde çalışıyorum. Bu nispeten kolay olmalı, standart C type_info bir sınıf vardır. Bu typeid adı/fonksiyon/sınıf vs ... içerir. ama ezilmiş. Çok yararlı değil. I. e. typeid(std::vector<int>).name() St6vectorIiSaIiEE döndürür.

Bir şekilde bu yararlı bir şey üretmek için var mı? İçin std::vector<int> gibi örnek yukarıda. Eğer sadece sigara-şablon sınıfları için çalışırsa, o zaman da iyi.

Çözüm gcc için çalışması gerekir, ama eğer port olsaydım daha iyi olurdu. Döndü olamaz o kadar önemli değil yani günlüğü için, ama hata ayıklama için yararlı olmalıdır.

CEVAP
27 Aralık 2010, PAZARTESİ


Dikkat Bu soruya verilen cevap alır ve GManNickG, değerli geri bildirim kodu biraz temizlemiş. İki versiyonu gibidir: C 11 özellikleri ve C 98 sadece özellikleri ile başka bir ile bir.

Dosya içindeyazın.hes

#ifndef TYPE_HPP
#define TYPE_HPP

#include <string>
#include <typeinfo>

std::string demangle(const char* name);

template <class T>
std::string type(const T& t) {

    return demangle(typeid(t).name());
}

#endif

Dosya içindetype.cpp(C 11) gerektirir

#include "type.hpp"
#ifdef __GNUG__
#include <cstdlib>
#include <memory>
#include <cxxabi.h>

std::string demangle(const char* name) {

    int status = -4; // some arbitrary value to eliminate the compiler warning

    // enable c  11 by passing the flag -std=c  11 to g  
    std::unique_ptr<char, void(*)(void*)> res {
        abi::__cxa_demangle(name, NULL, NULL, &status),
        std::free
    };

    return (status==0) ? res.get() : name ;
}

#else

// does nothing if not g  
std::string demangle(const char* name) {
    return name;
}

#endif

Kullanımı:

#include <iostream>
#include "type.hpp"

struct Base { virtual ~Base() {} };

struct Derived : public Base { };

int main() {

    Base* ptr_base = new Derived(); // Please use smart pointers in YOUR code!

    std::cout << "Type of ptr_base: " << type(ptr_base) << std::endl;

    std::cout << "Type of pointee: " << type(*ptr_base) << std::endl;

    delete ptr_base;
}

Yazdırır:

Ptr_base türü: Base*
Pointee türü: Derived

Linux 64 bit ve g 4.7.2 (Mingw32 win 32 XP SP2) g 4.7.2, g 4.9.0 20140302 (deneysel) tin 3.4 (trunk 184647), çınlama 3.5 (trunk 202594) ile test edilmiştir.

Olamaz C 11 özellikleri kullanırsanız, burada C 98, dosya yapılabilirtype.cppşimdi:

#include "type.hpp"
#ifdef __GNUG__
#include <cstdlib>
#include <memory>
#include <cxxabi.h>

struct handle {
    char* p;
    handle(char* ptr) : p(ptr) { }
    ~handle() { std::free(p); }
};

std::string demangle(const char* name) {

    int status = -4; // some arbitrary value to eliminate the compiler warning

    handle result( abi::__cxa_demangle(name, NULL, NULL, &status) );

    return (status==0) ? result.p : name ;
}

#else

// does nothing if not g  
std::string demangle(const char* name) {
    return name;
}

#endif


(8, 2013 Eylül) güncelleyin

15 ** çağrı başarılı olduğunda The accepted answer (as of Sep 7, 2013),,bir işaretçi bir yerel için ayrılan dizi yığın döndürür... ah!
Ayrıca eğer bir tampon sağlamak, abi::__cxa_demangle() öbek üzerinde tahsis edilecek varsayar unutmayın. On tampon yığın ayrılırken bir hata (gnu doktor):"Eğer output_buffer yeterince uzun değilse, realloc.*"Yığın işaretçisi realloc() arama... ah! (Ayrıca bakınız Igor Skochinsky'In yorum.)

Kolayca doğrulamak hem de bu hatalar: sadece azaltmak arabellek boyutu kabul cevabı (7 Eylül 2013) 1024 için daha küçük bir şey, örneğin 16, ve verecek bir şey olan bir isimdeğil15 (20**. daha uzun ^em>değildenir). Hala, sistemi ve derleyici en iyi duruma getirmeleri bağlı olarak, bir çıkış olacak: çöp / hiçbir şey / program çökebilir.
İkinci hata doğrulamak için: 1 arabellek boyutu ayarlamak için ve uzun 1 karakter daha olan bir şey ile arayın. Çalıştırdığınızda, program neredeyse kesinlikle yığın işaretçisi ile realloc() Ara dener gibi çöküyor.


(Dec eski cevap 27, 2010)

KeithB's code önemli değişiklikler:tampon ya da malloc ile ayrılmış veya BOŞ olarak belirtilmesi gerekir.Yığında ayırabilir.

Bilge bu durumu kontrol etmek için.

HAVE_CXA_DEMANGLE bulmak için başarısız oldum. Bu kodu derlemek bile garanti değil, ancak __GNUG__ kontrol ederim. Kimsenin daha iyi bir fikri olan?

#include <cxxabi.h>

const string demangle(const char* name) {

    int status = -4;

    char* res = abi::__cxa_demangle(name, NULL, NULL, &status);

    const char* const demangled_name = (status==0)?res:name;

    string ret_val(demangled_name);

    free(res);

    return ret_val;
}

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • bcbauer

    bcbauer

    7 ŞUBAT 2007
  • dhcrr's channel

    dhcrr's chan

    2 Ocak 2007
  • Mindy

    Mindy

    20 NİSAN 2006