Jak zaimplementowano środowisko wykonawcze obsługi wyjątków C++?

Jestem zaintrygowany tym, jak działa mechanizm obsługi wyjątków w C++. W szczególności, gdzie przechowywany jest obiekt exception i w jaki sposób propaguje się przez kilka zakresów, dopóki nie zostanie przechwycony? Czy jest przechowywany w jakimś globalnym obszarze?

Skoro to może być specyficzne dla kompilatora, czy ktoś mógłby to wyjaśnić w kontekście pakietu kompilatorów g++?

Author: Shog9, 2009-01-29

4 answers

Implementacje mogą się różnić, ale istnieją pewne podstawowe pomysły, które wynikają z wymagań.

Sam obiekt exception jest obiektem utworzonym w jednej funkcji, zniszczonym w wywołującym ją wywołaniu. W związku z tym zazwyczaj nie jest możliwe utworzenie obiektu na stosie. Z drugiej strony wiele obiektów WYJĄTKÓW nie jest zbyt dużych. Ergo, można utworzyć np. 32-bajtowy bufor i przepełnić stertę, jeśli większy obiekt wyjątku jest rzeczywiście potrzebny.

Co do faktycznego przeniesienia kontroli, istnieją dwie strategie. Jednym z nich jest zapisanie wystarczającej ilości informacji w samym stosie, aby rozluźnić stos. Jest to w zasadzie lista destruktorów do uruchomienia i programów obsługi wyjątków, które mogą wychwycić wyjątek. Gdy wystąpi wyjątek, Uruchom stos wykonujący te destruktory, aż znajdziesz pasujący haczyk.

Druga strategia przenosi te informacje do tabel poza stosem. Teraz, gdy wystąpi wyjątek, stos wywołań jest używany, aby dowiedzieć się, które zakresy są wprowadzone, ale nie wyszedł. Są one następnie sprawdzane w tabelach statycznych, aby określić, gdzie wyrzucony wyjątek będzie obsługiwany i które destruktory uruchamiają się pomiędzy nimi. Oznacza to, że na stosie jest mniej narzutów WYJĄTKÓW; adresy zwrotne i tak są potrzebne. Tabele są dodatkowymi danymi, ale kompilator może umieścić je w segmencie obciążonym zapotrzebowaniem programu.

 38
Author: MSalters,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-29 10:19:22

Jest to zdefiniowane w 15.1.

Rzut tworzy obiekt tymczasowy.
Sposób alokacji pamięci dla tego tymczasowego obiektu jest nieokreślony.

Po utworzeniu obiektu tymczasowego kontrola jest przekazywana do najbliższego modułu obsługi w stosie wywołań. odwijanie stosu między rzutu i punktu połowu. Gdy stos jest rozwijany, wszystkie zmienne stosu są niszczone w odwrotnej kolejności tworzenia.

Chyba że wyjątek zostanie ponownie wyrzucony czasownik niszczony jest na końcu przewodu, gdzie został złapany.

Notatka: jeśli złapiesz przez odniesienie, Referencja będzie odnosić się do tymczasowego, jeśli złapiesz przez wartość, tymczasowy obiekt zostanie skopiowany do wartości (i dlatego wymaga konstruktora kopiującego).

Porady S. Meyersa (Catch by const reference).

try
{
    // do stuff
}
catch(MyException const& x)
{
}
catch(std::exception const& x)
{
}
 18
Author: Martin York,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-08 15:58:34

Możesz zajrzeć tutaj , aby uzyskać szczegółowe wyjaśnienie.

Może również pomóc przyjrzeć się sztuczce używanej w prostym C, aby zaimplementować jakąś podstawową obsługę wyjątków. Wiąże się to z użyciem setjmp () i longjmp () w następujący sposób: pierwsza zapisuje stos w celu oznaczenia obsługi wyjątków (jak "catch"), podczas gdy druga jest używana do" rzucania " wartości. Wartość "rzucona" jest postrzegana tak, jakby została zwrócona z wywołanej funkcji. "Try block" kończy się, gdy setjmp () jest wywoływana ponownie lub gdy funkcja powróci.

 11
Author: Eduard - Gabriel Munteanu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-29 07:57:44

Wiem, że to stare pytanie, ale jest bardzo dobra ekspozycja, wyjaśniająca zarówno metody stosowane w każdym z gcc i VC tutaj: http://www.hexblog.com/wp-content/uploads/2012/06/Recon-2012-Skochinsky-Compiler-Internals.pdf

 8
Author: Jules May,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-22 08:29:12