Zobrazit předchozí téma :: Zobrazit následující téma |
Autor |
Zpráva |
bolejt

Založen: 02. 05. 2009 Příspěvky: 45
|
Zaslal: 6. říjen 2009, 23:32:11 Předmět: vice informací pro throw |
|
|
zkoušel jsem si vytvořit macro, které bych používal místo throw, protože vyhození výjimky standardně vypíše málo informací (název a what()). chtěl jsem, aby po vyhození výjimky byla zapsáno do logu informace o místě vyhození, výpis jsem si představoval nějaký pěkný, zhruba jako v javě:
kód: |
ExceptionName at file.cpp(functionOrMethod:234)
|
tyto informace můžou být pro mě přínosné, pokud to náhodou někde chudáku uživateli vyhodí výjimku.
po chvíli laborování a hrátky s makry a pak i s šablonami jsem dospěl k tomuto:
kód: |
template <typename Type>
inline void helper(const Type& t, const char* filename, const char* function, const int& line) {
std::clog << typeid(t).name() << " at " << filename << " (" << function << ':' << line << ')' << std::endl;
throw t;
}
#define _M_THROW(Exception) { \
helper(Exception, __FILE__, __func__, __LINE__); \
} |
po vyzkoušení jsem byl překvapen výstupem, např. pro runtime_exception:
kód: |
St13runtime_error at main.cpp (method:30) |
až teď vím, že type_info.name() dle standardu může vyhazovat naprosto cokoliv, klidně i prázdný řetězec.
používá někdo něco, nemá někdo řešení? nebo se musím smířit s trochu chudším nebo ošklivějším výstupem?
je to spíš taková hovadinka, uznávám...  _________________ Ball ball8; |
|
Návrat nahoru |
|
 |
Marek

Založen: 28. 07. 2007 Příspěvky: 1782 Bydliště: Velká Morava
|
Zaslal: 7. říjen 2009, 00:00:26 Předmět: |
|
|
Takový je holt GCC, u něj prostě name() vrací špatně čitelné názvy typů. Visual C++ je vrací tak, jak jsou ve zdrojáku, tedy např. "std::runtime_error".
V implementaci RTTI na GCC jsou mnohem horší věci, tedy že za určitých okolností ti může vrátit špatné type_info (na tom ale závisí třeba dynamic_cast). Celé RTTI je tam polofunkční a udělané spíš povrchně. Používej Visual C++, tam RTTI funguje vždy a jeho implementace je neprůstřelná (např. typeid na neexistujícím objektu namísto pádu hodí výjimku). _________________ AMD Open Source Graphics Driver Developer |
|
Návrat nahoru |
|
 |
Tringi

Založen: 28. 07. 2007 Příspěvky: 290
|
Zaslal: 7. říjen 2009, 08:26:20 Předmět: |
|
|
U GCC lze "mangled" název typu, tedy ten který dostaneš tím .name(), rozluštit pomocí funkce: __cxxabiv1::__cxa_demangle z #include <cxxabi.h>
A co se týče RTTI a dynamic_cast, tak u novějších GCC bych se toho vůbec nebál. Tak komplikovanou strukturu aby ti to začalo chybovat jen tak nenavrhneš, a pokud se vyhneš rozkládání C++ projektů do více modulů (DLL knihoven), tak jsi v klidu. Visual C++ bych až tolik neglorifikoval, jako Eosie, i když na vývoj aplikací pro Windows bývá (ale ne vždy) vhodnější než GCC  _________________ WWW | GitHub | TW |
|
Návrat nahoru |
|
 |
Marek

Založen: 28. 07. 2007 Příspěvky: 1782 Bydliště: Velká Morava
|
Zaslal: 7. říjen 2009, 15:47:41 Předmět: |
|
|
Tringi napsal: |
... a pokud se vyhneš rozkládání C++ projektů do více modulů (DLL knihoven)... |
No právě, to je ono. Když máš projekt, jehož veškerá funkcionalita je v pluginech, které mezi sebou komunikují (posílají si objekty a přetypovávají je na potomka), pak v tomto případě nemůžeš v G++ použít ani typeid, ani dynamic_cast, tzn. nemůžeš plně využít C++. No není to ostuda?
VC++ FTW.  _________________ AMD Open Source Graphics Driver Developer |
|
Návrat nahoru |
|
 |
Tringi

Založen: 28. 07. 2007 Příspěvky: 290
|
Zaslal: 7. říjen 2009, 19:19:28 Předmět: |
|
|
V nejnovějším MinGW 4.4.0 už přinejmenším používat třídy z namespace std mezi moduly, a vyhazovat std výjimky lze.
Pokud nepoužiješ nový přepínač -static-libgcc, tak je použita dynamická verze knihovny libstdc++-6.dll, která je sdílena mezi moduly. _________________ WWW | GitHub | TW |
|
Návrat nahoru |
|
 |
Marek

Založen: 28. 07. 2007 Příspěvky: 1782 Bydliště: Velká Morava
|
Zaslal: 7. říjen 2009, 21:10:03 Předmět: |
|
|
Jo, ale narážel jsem na to, že RTTI neprojde přes .so-boundary (u .dll platí asi to samé). Takže nejde vyhodit výjimku z dll, kde je deklarovaná, a chytit ji v druhém dll. _________________ AMD Open Source Graphics Driver Developer |
|
Návrat nahoru |
|
 |
Tringi

Založen: 28. 07. 2007 Příspěvky: 290
|
|
Návrat nahoru |
|
 |
bolejt

Založen: 02. 05. 2009 Příspěvky: 45
|
Zaslal: 8. říjen 2009, 13:57:31 Předmět: |
|
|
Eosie: s tím Visual C++ to na Debianu nebude snadné ale to jsem měl napsat v prvním příspěvku.
Tringy: použít "__cxa_demangle" bude asi jediná možnost pro hezký výpis. ještě vše relevantní obalím do "#if defined(__GNUC__)" a u ostatních kompilátorů budu předpokládat/věřit, že se v type_info::name() chovají pro mé potřeby správně... stejně lze vše odvodit z file:#line.
ad RTTI v GCC/MinGW, zajímavé info, díky. _________________ Ball ball8; |
|
Návrat nahoru |
|
 |
|