এই প্রশ্ন / উত্তরটি যে মনোযোগ পেয়েছে এবং GManNickG এর কাছ থেকে মূল্যবান প্রতিক্রিয়া পেয়েছে আমি কোডটি কিছুটা সাফ করেছি। দুটি সংস্করণ দেওয়া হয়েছে: একটি সি ++ 11 বৈশিষ্ট্যযুক্ত এবং অন্যটি কেবল সি ++ 98 বৈশিষ্ট্যযুক্ত।
ফাইল টাইপ। 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
ফাইল টাইপ। সি পি পি এ (সি ++ 11 প্রয়োজন)
#include "type.hpp"
#ifdef __GNUG__
#include <cstdlib>
#include <memory>
#include <cxxabi.h>
std::string demangle(const char* name) {
int status = -4;
std::unique_ptr<char, void(*)(void*)> res {
abi::__cxa_demangle(name, NULL, NULL, &status),
std::free
};
return (status==0) ? res.get() : name ;
}
#else
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();
std::cout << "Type of ptr_base: " << type(ptr_base) << std::endl;
std::cout << "Type of pointee: " << type(*ptr_base) << std::endl;
delete ptr_base;
}
এটি প্রিন্ট করে:
পিটিআর_বাসের Base*
ধরণ : পয়েন্টির ধরণ:Derived
জি ++ 4.7.2, জি ++ 4.9.0 20140302 (পরীক্ষামূলক), ঝাঁকুনি ++ 3.4 (ট্রাঙ্ক 184647), লঙ্ঘন 3.5 (ট্রাঙ্ক 202594) লিনাক্স bit৪ বিট এবং জি ++ ৪. M.২ (মিংডব্লু, উইন 32 এক্সপি এসপি 2) এর সাথে পরীক্ষিত।
আপনি যদি সি ++ 11 বৈশিষ্ট্যগুলি ব্যবহার করতে না পারেন, তবে এটি এখানে সি ++ 98 এ কীভাবে করা যায় তা ফাইল টাইপ। সি পি পি এখন:
#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;
handle result( abi::__cxa_demangle(name, NULL, NULL, &status) );
return (status==0) ? result.p : name ;
}
#else
std::string demangle(const char* name) {
return name;
}
#endif
(সেপ্টেম্বর 8, 2013 থেকে আপডেট)
গৃহীত উত্তর (সেপ্টেম্বর 7, 2013 হিসাবে) , যখন কলটি abi::__cxa_demangle()
সফল হয়, স্থানীয়কে একটি পয়েন্টার ফেরত দেয়, বরাদ্দ করা অ্যারের স্টোর ... আউট!
এছাড়াও মনে রাখবেন যে আপনি যদি বাফার সরবরাহ abi::__cxa_demangle()
করেন তবে এটি গাদাতে বরাদ্দ দেওয়া হবে বলে ধরে নিন। স্ট্যাকের উপর বাফার বরাদ্দ করা একটি বাগ (gnu ডক থেকে): "যদি output_buffer
যথেষ্ট দীর্ঘ না হয় তবে এটি ব্যবহার করে প্রসারিত হবে realloc
।" স্ট্যাকের দিকে একটি পয়েন্টারে কল realloc()
করছি ... আউট! (এছাড়াও ইগর স্কোচিনস্কির সদয় মন্তব্য দেখুন))
আপনি সহজেই এই বাগ উভয় যাচাই করতে পারেন: শুধু বাফারের আকার গৃহীত উত্তরে 1024 থেকে ছোট কিছু, উদাহরণস্বরূপ 16 কমাতে (7 সেপ্টেম্বর, 2013 হিসাবে), এবং এটি একটি নাম দিয়ে কিছু দিতে না 15 চেয়ে দীর্ঘতর (তাই realloc()
হয় বলা হয় না )। তবুও, আপনার সিস্টেম এবং সংকলক অপ্টিমাইজেশনের উপর নির্ভর করে আউটপুটটি হবে: আবর্জনা / কিছুই নয় / প্রোগ্রাম ক্র্যাশ।
দ্বিতীয় ত্রুটি যাচাই করতে: বাফারের আকারটি 1 এ সেট করুন এবং যার নামটি 1 টির চেয়ে বেশি লম্বা এমন কিছু দিয়ে কল করুন। আপনি যখন এটি চালান, প্রোগ্রামটি অবশ্যই নিশ্চিতভাবে ক্র্যাশ হয়ে যায় যখন এটি realloc()
স্ট্যাকের কোনও পয়েন্টার দিয়ে কল করার চেষ্টা করে ।
(27 ডিসেম্বর, 2010 এর পুরানো উত্তর)
গুরুত্বপূর্ণ পরিবর্তনগুলি করা KeithB এর কোড : বাফার পারেন malloc দ্বারা বরাদ্দ বা শূন্য হিসাবে নির্দিষ্ট করা হয়েছে। এটি স্ট্যাকের জন্য বরাদ্দ করবেন না।
সেই অবস্থানটিও পরীক্ষা করা বুদ্ধিমানের কাজ।
আমি খুঁজে পেতে ব্যর্থ 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;
}
#include <cxxabi.h>
। অন্যথায় দুর্দান্ত কাজ, ধন্যবাদ।