[解決済み] std::type_info::name の結果のアンマッチング
質問
私は現在、特に呼び出し関数に関する情報を表示することになっている、いくつかのロギングコードに取り組んでいます。これは比較的簡単なはずで、標準の C++ には
type_info
クラスがあります。これはtypeidされたクラス/関数/その他の名前を含んでいますが、それは混乱したものです。あまり有用ではありません。すなわち
typeid(std::vector<int>).name()
は返す
St6vectorIiSaIiEE
.
ここから何か有用なものを生み出す方法はないのでしょうか?例えば
std::vector<int>
のように。もし、テンプレート以外のクラスでしか機能しないのであれば、それも結構です。
解決策はgccでも動くはずですが、移植できればもっといいんですけどね。ロギング用なので、オフにできないほど重要ではありませんが、デバッグには役立つはずです。
解決方法は?
この質問/回答が注目されていること、また、以下のような貴重なフィードバックがあることを考えると GManNickG からの貴重なフィードバックもあり、私はコードを少し整理しました。C++11の機能を備えたバージョンと、C++98の機能のみを備えたバージョンの2つを用意しました。
ファイル中の type.hpp
#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
ファイル内の type.cpp (C++11が必要)
#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
使用方法
#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;
}
印刷されます。
ptr_base のタイプです。
Base*
pointee の型。
Derived
Linux 64bitとg++ 4.7.2 (Mingw32, Win32 XP SP2)で、g++ 4.9.0 20140302 (experimental), clang++ 3.4 (trunk 184647), clang 3.5 (trunk 202594) でテストしています。
C++11の機能を使用できない場合、C++98でできる方法を紹介します。ファイル type.cpp ができました。
#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
(2013年9月8日より更新)
回答受付中(2013年9月7日現在)
への呼び出しは
abi::__cxa_demangle()
の呼び出しが成功した場合です。
はローカルでスタックに割り当てられた配列へのポインタを返します。
...痛っ!
また、バッファを提供する場合、注意してください。
abi::__cxa_demangle()
はそれがヒープ上に確保されると仮定していることにも注意してください。バッファをスタックに割り当てるのはバグです(gnu docより)。
もし
output_buffer
が十分な長さでない場合、それを展開するために
realloc
."
呼び出し
realloc()
をスタックへのポインタで呼び出す
...痛い! (参照
イゴール スコチンスキー
の親切なコメントもご覧ください)。
これらのバグは簡単に確認することができます。
ではなく
15 よりも長い名前 (つまり
realloc()
は
ではなく
は呼び出されない)。それでも、システムやコンパイラの最適化によっては、出力は「ゴミ」「何もない」「プログラムのクラッシュ」となります。
2つ目のバグを検証するために:バッファサイズを1に設定し、名前が1文字より長いもので呼び出します。これを実行すると、ほぼ間違いなくプログラムは
realloc()
をスタックへのポインターで呼び出そうとするためです。
(2010年12月27日の古い回答)
重要な変更点は KeithB のコード : バッファはmallocで確保するか、NULLを指定する必要があります。 スタック上に確保してはいけません。
その状態も確認するのが賢明です。
を見つけられませんでした。
HAVE_CXA_DEMANGLE
. 私は
__GNUG__
をチェックしますが、それはコードがコンパイルされることさえ保証しません。誰か良いアイデアを持っていますか?
#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;
}
関連
-
[解決済み】コンストラクターでのエラー:識別子を期待されますか?
-
[解決済み】C++の変数はイニシャライザーを持っているが、不完全な型?
-
[解決済み] 非静的データメンバの無効な使用
-
[解決済み] explicit キーワードの意味は?
-
[解決済み] 文字列の単語を反復処理するにはどうすればよいですか?
-
[解決済み] using namespace std;」はなぜバッドプラクティスだと言われるのですか?
-
[解決済み] ルール・オブ・スリーとは?
-
[解決済み] C++でextern "C "を使用した場合の効果は?
-
[解決済み] g++とgccの違いは何ですか?
-
[解決済み】C/C++の"-->"演算子とは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] string does not name a type Errorが発生するのはなぜですか?
-
[解決済み】C++エラー:の初期化に一致するコンストラクタがありません。
-
[解決済み] 式はクラス型を持つ必要があります。
-
[解決済み】ファイルから整数を読み込んで配列に格納する C++ 【クローズド
-
[解決済み】1つ以上の多重定義されたシンボルが見つかる
-
[解決済み】標準ライブラリにstd::endlに相当するタブはあるか?
-
[解決済み】C++ - ステートメントがオーバーロードされた関数のアドレスを解決できない。
-
[解決済み】Visual Studioのデバッガーエラー。プログラムを開始できません 指定されたファイルが見つかりません
-
[解決済み] C++11で "auto "で演繹した場合のlambdaの型は何ですか?
-
[解決済み] CまたはC++でコールスタックを印刷する