C++ a výjimka v destruktoru

sobol

C++ a výjimka v destruktoru
« kdy: 04. 02. 2014, 19:14:38 »
Dobry den, puvodne jsem si chtěl zjistil, co se deje, když nastane výjimka v destruktoru a tak jsem si napsal kratky kod, který by mel na stdout vypisovat, co se zrovna deje. Zkrachoval jsem ale na tom, ze vypisovani vůbec nefunguje. Je, prosim, chyba v mem kodu? Dekuji

Kód: [Vybrat]
#include "stdafx.h"
#include <iostream>

using namespace std;

class A
{
A()
{
cout << "konstruktor";
}

~A()
{
cout << "destruktor";
}
};

class B
{
B()
{
cout << "konstruktor B";
}

~B()
{
cout << "destructor B";

throw new int(5);
}
};

int _tmain(int argc, _TCHAR* argv[])
{
int i = 1;
if (i=1)
{
A a();
B b();
}
/*
try
{

A a();
B b();
}
catch (...)
{
cout << "err";
}
*/
char ch[10];
cin >> ch;

return 0;
}
« Poslední změna: 04. 02. 2014, 19:27:51 od Petr Krčmář »


tadeas

Re:C++ a výjimka v destruktoru
« Odpověď #1 kdy: 04. 02. 2014, 19:46:03 »
  • if (a=1)... - asi má být (a==1)
  • konstruktor a destruktor musejí byt public když je voláš zvenku (z main)
  • A a() - má být bez závorek (tvrdí clang)

S těmito úpravami (plus pár drobností jako int main) mi to funguje.

tadeas

Re:C++ a výjimka v destruktoru
« Odpověď #2 kdy: 04. 02. 2014, 19:47:36 »
Ještě přidám ten upravený, funkční kód.
Kód: [Vybrat]
#include <iostream>

using namespace std;

class A
{
    public:
    A()
    {
        cout << "konstruktor";
    }

    ~A()
    {
        cout << "destruktor";
    }
};

class B
{
    public:
    B()
    {
        cout << "konstruktor B";
    }

    ~B()
    {
        cout << "destructor B";

        throw new int(5);
    }
};

int main(int argc, char* argv[])
{
    int i = 1;
    if (i == 1)
    {
        A a;
        B b;
    }

    return 0;
}

Kód: [Vybrat]
prg-mpskl:prog tmoravec$ g++ destructor.cpp
prg-mpskl:prog tmoravec$ ./a.out
libc++abi.dylib: terminating with uncaught exception of type int*
konstruktorkonstruktor Bdestructor BAbort trap: 6
prg-mpskl:prog tmoravec$

Re:C++ a výjimka v destruktoru
« Odpověď #3 kdy: 04. 02. 2014, 22:05:30 »
Výjimka v destruktoru je výborná věc, pozor jenom na to, že masa podprůměrných céčkařů tady bude křičet a dupat nožičkama, že je to evil evil evil asi jako goto v Céčku.

Výjimka v destruktoru se provádí tak, jaky by v destruktoru byl return. Tedy destruktor se považuje za vykonaný, i když skončil výjimkou. Jestli se provádí nějaký stack unwind, tak maximálně v rámci destruktoru. Následně se děje to, že bez ohledu na to, jak skončil destruktor, program normálně pokračuje v destrukci objektu, jako by se nechumelilo až do okamžiku, kdy je objekt úplně zničený. Pak ale nastane zásadní změna. Bez výjimky by program pokračoval dalším příkazem následujícím po destrukci objektu. Pokud však destruktor vyhodil výjimku, pokračuje se hledáním prvního exception handleru, který by mohl výjimku odchytit, přičemž se zahájí stack unwind jako obvykle.

Takový drobný problém. delete obj

Chce to vyzkoušet, ale logika říká, že pokud destrukce objektu skončí výjimkou, paměť se neuvolní. Je samozřejmě možné že ano, ale chce to vyzkoušet i v případě, že delete byl přetížený (tam by se pak volal operátor, který se ale při výjimce nemá co volat). Odlišná situace je, pokud by obj měl virtuální destruktor, tam se myslím delete zavola ( jako poslední akce destrukce objektu). Pro jistotu je lepší používat chytrý ukazatel.

Výjimka v destrukoru má neocenitelnou funkci přerušení programu a podání zprávy v okamžiku, kdy součastí destrukce je operace, která selhala a defacto vylučuje další běh programu... je to prostě výjimka. Příklad... flush nějakého bufferu.

Proč je to tak kritické téma?

Jednou z věcí je, že hodně programátorů si neuvědomuje, co to všechno znamená. Jak moc musí změnit své programátorské návyky. Je potřeba striktně dodržovat RAII (to bolí). Je potřeba změnit způsob destrukce polí (to bolí ještě víc), protože co by se mělo dít, když při destrukci pole dojde k výjimce u pátého prvku z deseti? Správně nic, destrukce by měla pokračovat, pouze v případě, že by došlo k další výjimce, je to chyba double exception. Zkuste tohle v STL!!!!

A to je třetí a nejzásadnější problém. Spousta standardních knihoven a překladačů s tím má prostě problém.  Asi z toho důvodu jsou výjimky v destruktorech v C++11 by default zakázány (a volají automaticky terminate) ale naštěstí je lze explicitně u jednotlivých objektů povolovat.

Nicméně dá se to nádherně využívat.

Ještě k řešení double exception
Kód: [Vybrat]
~Object() { try {
    ....
} catch (...) {
 //pokud leti vyjimka, neni dobry napad hazet dalsi
  if (!std::uncaught_exception())  throw;
}}


Sten

Re:C++ a výjimka v destruktoru
« Odpověď #4 kdy: 04. 02. 2014, 22:51:44 »
Takový drobný problém. delete obj

Chce to vyzkoušet, ale logika říká, že pokud destrukce objektu skončí výjimkou, paměť se neuvolní. Je samozřejmě možné že ano, ale chce to vyzkoušet i v případě, že delete byl přetížený (tam by se pak volal operátor, který se ale při výjimce nemá co volat). Odlišná situace je, pokud by obj měl virtuální destruktor, tam se myslím delete zavola ( jako poslední akce destrukce objektu). Pro jistotu je lepší používat chytrý ukazatel.

Dealokace se provede vždy.

ISO C++ 2011 5.3.5p7:

[…] The deallocation function is called regardless of whether the destructor for the object or some element of the array throws an exception.

Jednou z věcí je, že hodně programátorů si neuvědomuje, co to všechno znamená. Jak moc musí změnit své programátorské návyky. Je potřeba striktně dodržovat RAII (to bolí). Je potřeba změnit způsob destrukce polí (to bolí ještě víc), protože co by se mělo dít, když při destrukci pole dojde k výjimce u pátého prvku z deseti? Správně nic, destrukce by měla pokračovat, pouze v případě, že by došlo k další výjimce, je to chyba double exception. Zkuste tohle v STL!!!!

V STL to nejde, protože clear je nothrow.

ISO C++ 2011 23.2.1p11:
[…] no erase(), clear(), pop_back() or pop_front() function throws an exception […]

A to je třetí a nejzásadnější problém. Spousta standardních knihoven a překladačů s tím má prostě problém.  Asi z toho důvodu jsou výjimky v destruktorech v C++11 by default zakázány (a volají automaticky terminate) ale naštěstí je lze explicitně u jednotlivých objektů povolovat.

No, je to hlavně z toho důvodu, že výjimky v destruktorech jsou tak ošidné, že lidé uvnitř ISO C++ se dohodli na tom, že to má být povolené jenom tam, kde programátor explicitně uvede, že ví, co dělá.

Ještě k řešení double exception
Kód: [Vybrat]
~Object() { try {
    ....
} catch (...) {
 //pokud leti vyjimka, neni dobry napad hazet dalsi
  if (!std::uncaught_exception())  throw;
}}

Já používám
Kód: [Vybrat]
~Object()
try {

} catch (...) {
if (std::uncaught_exception())
return;
}

Je to trochu odlišné, protože to chytá i destruktory členů, ale ty by stejně neměly vyhazovat při uncaught_exception, takže výsledek je v podstatě stejný.


JSH

Re:C++ a výjimka v destruktoru
« Odpověď #5 kdy: 04. 02. 2014, 23:25:45 »

Pokud z destruktoru vyletí výjimka během stack unwindingu, tak se nezahodí, ale volá se std::terminate. Což obvykle znamená, že se destruktor ukončí i se zbytkem programu. Pro terminate se dá nastavit vlastní handler, ale v něm se stejně moc zachránit nedá.

> std::uncaught_exception

Je hack, který přináší vlastní řadu problémů. Např. při stack unwindingu může někde v hloubi destruktoru vyletět výjimka, která se o kousek dál chytne. Házející kód to ale neví, takže se musí spolehnout na uncaught_exception, která samozřjmě vrací true. Tohle zneškodní výjimky i tam, kde můžou normálně lítat. Více zde : http://www.gotw.ca/gotw/047.htm

Shrnutí

Pokud budeš házet výjímky ven z destruktorů, počítej s problémy. Ty prostě budou ať použiješ jakékoliv geniální triky. Navíc jsou to málo vykonávané kusy kódu, takže se ty problémy podle zákona schválnosti nejspíš projeví ve chvíli kdy bude šéf předvádět program důležitému zákazníkovi. Opravdu to nejde udělat jinak?

Re:C++ a výjimka v destruktoru
« Odpověď #6 kdy: 05. 02. 2014, 08:20:25 »

Pokud z destruktoru vyletí výjimka během stack unwindingu, tak se nezahodí, ale volá se std::terminate. Což obvykle znamená, že se destruktor ukončí i se zbytkem programu. Pro terminate se dá nastavit vlastní handler, ale v něm se stejně moc zachránit nedá.

No tohle je přesně ta krásná vlastnost C++, kterou naprosto nechápu... respektivě chápu, že lidi z ISO nebyli schopni najít rozumné řešní, tak se k tomu chovají jako pštros, schovají hlavu do písku a řeší to tím nejhorším způsobem, jakým se to řešit dá.

Základní pravidla dobrého programátora: "Program by neměl spadnout". Nelze zákazníkovy vysvětlovat, že program spadnul jen proto, že mu selhala nějaká operace a zrovna zároveň mu spadla síť, takže došlo k dvou problémům naráz a program to psychicky neunesl a zhroutil se

http://www.gotw.ca/gotw/047.htm

Nesmíte věřit všemu, co se na internetu píše. Ten člověk má sice pravdu, že ta funkce uncaught_exception je hloupá a vrací true, když probíhá stack unwinding, ale už nevyřeší, zda výjimka vyhozena v tomto okamžiku způsobí problém.

Jenže už to neumí vyřešit a navíc ukazuje příklady chybného použití této funkce. Nejprve ale jedna malá analýza.

V případě, že nechci použít uncaught_exception, tak ja budu výjimku v destruktoru řešit? No asi nijak, tak jak to řeši většina běžných coderů
Kód: [Vybrat]
~Object() {
try {
  ....
} catch (...) {}
}

Když budu chtít být podctivější, napíšu to takto

Kód: [Vybrat]
~Object() {
try {
  ....
} catch (std::exception &e) {
   logException(e);
}
}


... tedy za předpokladu, že mi funkce logException nevyhodí výjimku. Benefit, který mi přináší použití std::uncaught_exception je ten, že mi říká naopak... "nyní je bezpečné výjimku vyhodit, takže se ten problém dostane k někomu povolanějšímu.". Samozřejmě, že není blbej nápad to zalogovat tak jako tak

Kód: [Vybrat]
~Object() {
try {
  ....
} catch (std::exception &e) {
   logException(e);
   if (!std::uncaught_exception()) throw;
}
}

To se mi tedy nejhůře může stát je, že se destruktor bude chcovat tak, jako by se choval v okamžiku, kdy bych ho deklaroval nothrow() a výjimku si pořešil uvnitř sám. Kde v tom vidíte problém?

Zpět k tomu odkazu. Ten člověk nakonec demonstruje, že nerozumí nástroji, který se mu dostal do ruky. Například,

Kód: [Vybrat]
   //  Variant: Another wrong solution
    //
    Transaction::~Transaction() {
      if( uncaught_exception() ) {
        RollBack();
      }
    }

Má pravdu, je to wrong solution a je to také ukázka nesprávné použití uncaught_exception(). On totiž nepoužívá tu funkci proto, aby se vyhnul dvojitý výjimce, kterou zrovna řeší, on to používá proto, že má obavu, že by Rollback() vyhodil výjimku a způsobil problém. A to je špatné použití uncaught_exception. Tak se to opravdu dělat nemá a ten kdo to použije si skutečně koleduje o malér. Správná řešení je:


Kód: [Vybrat]
    Transaction::~Transaction() {
      try {
        RollBack();
      } catch (...) {
        if (!std::uncaught_exception()) throw;
      }
    }


No je to pořád stejné, pořád to je jen o tom, že se destruktor snaží rozhodnout, zda je bezpečné hodit výjimku nebo ne. To co autor navrhuje v tom článku nakonec je opravdu z říše pohádek... použití zavíracích funkcí totálně zničíme koncept RAII. Pokud už bych v tom viděl výhodu, tak maximálně v situaci, kdy zavírám potencionálně nebezpečnou operaci v destruktoru, a chci mít jistotu, že výjimka propadne až ke mě. Ta možnost ručního uzavření by tam mohla samozřejmě být, stejně tak jako můj objekt pro transakci obsahuje i funkci rollback() a její implicitní volání řeší pouze případy, kdy je potřeba transakci rollbacknout během výjimky. Ale nelze to vzít jako konečné řešení a výjimky zakázat.

Kód: [Vybrat]
  //  The right solution
    //
    T::~T() /* throw() */ {
      // ... code that won't throw ...
    }

Pan autor má smysl pro humor. Kolikrát mu program spadnul před zákazníkem na SIGABORT?

Kód: [Vybrat]
//  Alternative right solution
    //
    T::Close() {
      // ... code that could throw ...
    }

    T::~T() /* throw() */ {
      try {
        Close();
      } catch( ... ) {
      }
    }

Tady ukazuje, že pan autor vlastně neudělal nic. Vyjímku zaignoruje (ani ji nezaloguje) a program sice nespadne, ale rozhodně nemusí fungovat. Pokud by do větve catch přidal

Kód: [Vybrat]
        if (!std::uncaught_exception()) throw;

Rozhodně by svému kódu neublížil.

Opravdu to nejde udělat jinak?

Jde, ale musí se to umět.


[…] The deallocation function is called regardless of whether the destructor for the object or some element of the array throws an exception.

Dík, to jsem nevěděl, domníval jsem se, že u přetížených operátorů to bude problém... v "některých" překladačích.


Já používám
Kód: [Vybrat]
~Object()
try {

} catch (...) {
if (std::uncaught_exception())
return;
}

To jsem používal, ale mám pocit, že s tím má někdo problém... Mám pocit, že ve Visual Studiu se to nechovalo úplně správně. A zápis občas rozhodil nějaká IDE (myslím že eclipse).


Re:C++ a výjimka v destruktoru
« Odpověď #7 kdy: 05. 02. 2014, 08:29:16 »
Malá poznámka k tomu Rollback

Citace
//  Variant: Another wrong solution
    //
    Transaction::~Transaction() {
      if( uncaught_exception() ) {
        RollBack();
      }
    }

Já jsem si neuvědoml, že tam nemá vykřičník. Takže ten rollback vlastně volá jen když letí výjimka. No to už je totální blbost a za tenhle kód bych strhával prémie!

Zrovna u transakcí se používá explicitní commit a implicitní rollback v destruktoru. Každopádně platí oboje, ať už s vykřičníkem, nebo bez, oboje je špatné použití uncaught_exception.


gamer

Re:C++ a výjimka v destruktoru
« Odpověď #9 kdy: 05. 02. 2014, 09:12:30 »
Vyhazovat výjimky v destruktoru je zakázané snad ve všech coding standards, které jsem kdy viděl. Například v "101 Rules, Guidelines, and Best Practices":

Destructors, deallocation, and swap never fail.
Summary
Everything they attempt shall succeed: Never allow an error to be reported from a destructor, a resource deallocation function (e.g., operator delete), or a swap function. Specifically, types whose destructors may throw an exception are flatly forbidden from use with the C++ standard library.

Pokud si někdo myslí, že je lepší než tvůrci všech možných coding standards, tak ať si výjimky v destruktorech vyhazuje, ale prosím neprezentovat to jako skvělou věc ostatním.

JSH

Re:C++ a výjimka v destruktoru
« Odpověď #10 kdy: 05. 02. 2014, 09:52:10 »
No tohle je přesně ta krásná vlastnost C++, kterou naprosto nechápu... respektivě chápu, že lidi z ISO nebyli schopni najít rozumné řešní, tak se k tomu chovají jako pštros, schovají hlavu do písku a řeší to tím nejhorším způsobem, jakým se to řešit dá.
Já tuhle vlastnost C++ naopak docela chápu. Lidi z ISO nebyli schopni najít řešení, které by nějak konzistentně fungovalo. Takže místo toho aby z toho udělali nedefinovanou/nespecifikovanou operaci, tak řekli že je to porušení invariantů +- na úrovni assertu. A pokud chci házet z destruktorů, tak to musím překladači explicitně říct.

Jak řešit vyhození výjimky při unwindingu jiné? Potichu ignorovat původní, nebo novou výjimku? Nebo je nějak poskládat?

S házením výjimek z destruktoru mám i jeden spíš filosofický a sémantický problém:

Vyhozená výjimka znamená, že se operace neprovedla a objekt by měl být v nějakém konzistentním stavu. Ideálně tak, jak byl před začátkem té chybné operace aby se dala třeba zopakovat. Akorát že v destruktoru je to naprosto nechtěné chování. Takže pro destruktor se musí napsat úplně znova všechno, co zavání rollbackem(v rámci toho rušeného objektu), protože ty operace místo návratu musí pokračovat v likvidování. To znamená, že ten házející destruktor musí pro případ, že by vyhodil výjimku obsahovat i nějaký kompletní úklid. Nepodobá se to tak trochu neházejícímu destruktoru?

A co se dá dělat v případě, že destruktor vyhodí výjimku? Objekt už neexistuje, takže se z toho nedá nijak vzpamatovat. Musí se kompletně zopakovat celá operace, jejíž závěr (třeba zápis patičky nějakého souboru) takhle selhal. Pokud ten házející závěr vyhodím do vlastní metody, tak pokud vyhodí výjimku, tak ji můžu chytnout ještě před zlikvidováním objektu a možná to půjde nějak zachránit. Házející destruktor sice zahlásí chybu, ale všechno zlikviduje jako by se nechumelilo. Něco jako by word při vypínání zahlásil, že se soubor nepodařilo uložit, ale dokument by stejně zavřel.

Máte nějaký příklad, kdy je házení z destruktorů rozumné řešení? Já jsem se bohužel s takovým ještě nesetkal. Ve všech případech, kdy jsem měl chuť házet z destruktoru, to bylo jen mojí leností a pokud jsem si líp promyslel chybové situace, tak mi ty házející kousky kódu vybublaly z destruktorů ven.

Pokud si někdo myslí, že je lepší než tvůrci všech možných coding standards ...

Slyšel jsem krásný názor ve smyslu, že by se měl člověk snažit programovat tak, jak by programoval někdo daleko hloupější. Dává to smysl. Ve chvíli, kdy píšu něco na hranici svých možností, tak už nemám na to, řešit případné problémy.

Re:C++ a výjimka v destruktoru
« Odpověď #11 kdy: 05. 02. 2014, 10:49:43 »
Já tuhle vlastnost C++ naopak docela chápu. Lidi z ISO nebyli schopni najít řešení, které by nějak konzistentně fungovalo. Takže místo toho aby z toho udělali nedefinovanou/nespecifikovanou operaci, tak řekli že je to porušení invariantů +- na úrovni assertu. A pokud chci házet z destruktorů, tak to musím překladači explicitně říct.

Jak řešit vyhození výjimky při unwindingu jiné? Potichu ignorovat původní, nebo novou výjimku? Nebo je nějak poskládat?
Co třeba rezoluční funkci? Když už nás někdo nutí implementovat si vlastní verzi terminate() tak taky mohli zavést rezoluční funkci na situaci, kdy vznikne double exception. Ona by možná stačila funkce, která by situaci řešila než volat terminate a tvářit se jako že programátor je blbec,

void on_double_exception()  throw();

Pokud by nastala dvojitá vyjímka, program by ihned skočil do této funkce, s tím, že by to bylo součástí nějakého univerzální catch handleru před tím, než by se pokračovalo v unwindingu původní výjimky

Kód: [Vybrat]
void my_on_double_exception() throw {
try {
   throw;
} catch (std::exception &e) {
   logException(e);
}
}

std::set_on_double_exception(&my_on_double_exception);

V C++11 existují lepší nástroje na vyzvednutí aktivní výjimky, tam by taková konstrukce nebyla potřeba

Myšlení bolí, a úředníci velice neradi myslí.



Vyhozená výjimka znamená, že se operace neprovedla a objekt by měl být v nějakém konzistentním stavu. Ideálně tak, jak byl před začátkem té chybné operace aby se dala třeba zopakovat. Akorát že v destruktoru je to naprosto nechtěné chování. Takže pro destruktor se musí napsat úplně znova všechno, co zavání rollbackem(v rámci toho rušeného objektu), protože ty operace místo návratu musí pokračovat v likvidování. To znamená, že ten házející destruktor musí pro případ, že by vyhodil výjimku obsahovat i nějaký kompletní úklid. Nepodobá se to tak trochu neházejícímu destruktoru?

Nevidím v tom problém. Výjimka vyhozena v destruktoru znamená, že objekt byl přesto zničený. Výjimka má za úkol přerušit další běh programu a nasměrovat ho k nejbližšímu exception handleru a předat mu chybový objekt. Nemusí to nutně znamenat, že se operace rollbackne. Neříká to nic o tom, že operace nebyla provedena. Je samozřejmě lepší, když funkce, která hodila výjimku uveden objekt do původního stavu, ale to je pouze SHOULD, nikoliv MUST. V případě výjimky destruktoru jde vlastně o uvedení objektu do původního stavu a jeho následnou destrukci, což vede k tomu, co jsem říkal a žádný logický rozpor tam není.

A co se dá dělat v případě, že destruktor vyhodí výjimku? Objekt už neexistuje, takže se z toho nedá nijak vzpamatovat. Musí se kompletně zopakovat celá operace, jejíž závěr (třeba zápis patičky nějakého souboru) takhle selhal. Pokud ten házející závěr vyhodím do vlastní metody, tak pokud vyhodí výjimku, tak ji můžu chytnout ještě před zlikvidováním objektu a možná to půjde nějak zachránit.
Jak? Co děláte, když vám ve standardním C funkce fclose() oznámí chybu? Zpravidla nic, zaignorujete to.

Citace
Upon successful completion 0 is returned. Otherwise, EOF is returned and the global variable errno is set to indicate the error. In either case any further access (including another call to R fclose ()) to the stream results in undefined behavior.

Házející destruktor sice zahlásí chybu, ale všechno zlikviduje jako by se nechumelilo. Něco jako by word při vypínání zahlásil, že se soubor nepodařilo uložit, ale dokument by stejně zavřel.

To je validní řešení. Destruktor je něco jako konečné řešení. V destruktoru by se neměla dělat validace požadavku. Není problém volání metody Word::save() před jeho destrukcí. Nehledě na to, že je dost diskutabilní, jestli by destruktor objektu Word měl volat save. Nicméně destruktor nějakého bufferovaného streamu by měl zavolat flush() (viz dále)

Máte nějaký příklad, kdy je házení z destruktorů rozumné řešení? Já jsem se bohužel s takovým ještě nesetkal. Ve všech případech, kdy jsem měl chuť házet z destruktoru, to bylo jen mojí leností a pokud jsem si líp promyslel chybové situace, tak mi ty házející kousky kódu vybublaly z destruktorů ven.

Kód: [Vybrat]
~WriteBuffer() {
try {
flush();
} catch (...) {
if (!std::uncaught_exception())
    throw;
}
}


Kód: [Vybrat]
Transaction::~Transaction() {
try {
rollback();
} catch (...) {
//catch exception if we are in exception
if (!std::uncaught_exception()) throw;
}
}
(ukázky z mého kódu)


Re:C++ a výjimka v destruktoru
« Odpověď #12 kdy: 05. 02. 2014, 11:05:40 »
Vyhazovat výjimky v destruktoru je zakázané snad ve všecEverything they attempt shall succeed: Never allow an error to be reported from a destructor, a resource deallocation function (e.g., operator delete), or a swap function. Specifically, types whose destructors may throw an exception are flatly forbidden from use with the C++ standard library.

Pokud si někdo myslí, že je lepší než tvůrci všech možných coding standards, tak ať si výjimky v destruktorech vyhazuje, ale prosím neprezentovat to jako skvělou věc ostatním.
Považujte mě za génia (minimálně za člověka, který 20 let programuje z toho 15 let v C++). Ale tvrdím, že standardní C++ knihovna byla napsána dementy pro dementy. Spoustu věcí v ní nejde, takže už jí několik let (bude to za chvíli přes 10) nepoužívám , maximálně tak okrajově.

Zákaz výjimek v destruktorech považuju za vážné narušení konceptu RAII a je mi fuk, že to zakazuje tisíce a jeden coding standard, protože RAII je nad tím a jakékoliv jeho narušení znamená, že se na to nemohu spolehnout. Lidi co vymýšlely tyhle coding standardy samozřejmě častokrát RAII nemají v krvi, takže vymýšlí blbosti. Je to trošku jiné programování a denně se kolem přesvědčuju, že ho ovládá tak jeden člověk z deseti.

gamer

Re:C++ a výjimka v destruktoru
« Odpověď #13 kdy: 05. 02. 2014, 11:15:33 »
Považujte mě za génia (minimálně za člověka, který 20 let programuje z toho 15 let v C++). Ale tvrdím, že standardní C++ knihovna byla napsána dementy pro dementy. Spoustu věcí v ní nejde, takže už jí několik let (bude to za chvíli přes 10) nepoužívám , maximálně tak okrajově.

Zákaz výjimek v destruktorech považuju za vážné narušení konceptu RAII a je mi fuk, že to zakazuje tisíce a jeden coding standard, protože RAII je nad tím a jakékoliv jeho narušení znamená, že se na to nemohu spolehnout. Lidi co vymýšlely tyhle coding standardy samozřejmě častokrát RAII nemají v krvi, takže vymýšlí blbosti. Je to trošku jiné programování a denně se kolem přesvědčuju, že ho ovládá tak jeden člověk z deseti.

No super, máme tady geniálního programátora... I kdyby to byla pravda (což si nemyslím), tak kód napsaný geniálním programátorem je prakticky nepoužitelný, protože ho "normální" programátoři nedokáží udržovat.

Flash

Re:C++ a výjimka v destruktoru
« Odpověď #14 kdy: 05. 02. 2014, 11:33:17 »
To je teď nějaká móda, označovat kódy za "příliš sofistikované" a doporučovat psát hloupé kódy, které sice budou neefektivní, ale rozumí jim každý jouda? Já to vidím tak, že když se někdo, kdo nezná jazyk do hloubky, pokouší upravovat kód od člověka, který ten jazyk zná jako svoje boty, tak na tom nezřídka pohoří a pak začne trousit kydy o nepoužitelném kódu, místo aby si uvědomil, že nepoužitelný není ten kód, ale on. Místo úchylných požadavků, aby profesionálové psali jako začátečníci, by se spíš měl zavřít do knihovny a to co mu není jasné, se doučit.