Po co łapać wyjątek jako odniesienie do stałej?

84

Wiele razy słyszałem i czytałem, że lepiej jest wychwycić wyjątek jako odniesienie do stałej, a nie jako odniesienie. Dlaczego jest:

try {
    // stuff
} catch (const std::exception& e) {
    // stuff
}

lepszy niż:

try {
    // stuff
} catch (std::exception& e) {
    // stuff
}
Cairol
źródło

Odpowiedzi:

67

Potrzebujesz:

  • odniesienie, dzięki czemu można uzyskać dostęp do wyjątku w sposób polimorficzny
  • const, aby zwiększyć wydajność i powiedzieć kompilatorowi, że nie zamierzasz modyfikować obiektu

Ta ostatnia nie jest tak ważna jak pierwsza, ale jedynym prawdziwym powodem usunięcia stałej byłoby zasygnalizowanie, że chcesz wprowadzić zmiany w wyjątku (zwykle przydatne tylko wtedy, gdy chcesz ponownie wrzucić go z dodanym kontekstem na wyższy poziom) .

Kornel Kisielewicz
źródło
1
„powiedz kompilatorowi, że nie zamierzasz modyfikować obiektu” - przypuszczam, że może to być przydatne, jeśli przekazujesz obiekt jako parametr do wywołania funkcji.
Craig McQueen
1
co masz na myśli mówiąc „polimorficzny dostęp do wyjątku”?
mango
3
@mango prawdopodobnie oznacza, że jest zdolny do wywoływania funkcji wirtualnego (na przykład std::exception„s what()funkcji). Jeśli złapiesz według wartości, nie możesz wywołać tej funkcji i uzyskać oryginalnych szczegółów wyjątku.
MM
11
spojrzałem na zespół wyprodukowany przez apple clang 7 i przez gcc 5 (z optymalizacją O3) i nie widzę żadnej różnicy między montażem const ref i non-const ref. Więc myślę, że nie ma różnicy w optymalizacjach dla gcc i apple clang
Vasiliy Soshnikov
2
Kompilator może łatwo zobaczyć, które obiekty modyfikujesz, a które nie ( SSA i ciągła propagacja). Potrzebne jest lepsze wyjaśnienie (czy to mit?).
rustyx
31

W zasadzie nie ma żadnego powodu.

Obiekty wyjątków żyją we własnej przestrzeni pamięci †, więc nie musisz się martwić o przechwytywanie wyjątków utworzonych w tymczasowych wyrażeniach.

Wszystko, co robisz, to obiecywanie, że nie zmodyfikujesz obiektu wyjątku, ale ponieważ obiekty wyjątków powinny mieć niezmienny interfejs , tak naprawdę nie ma tu nic praktycznego.

Jednak może sprawić, że poczujesz się ciepło i przytulnie, gdy to przeczytasz - tak to jest dla mnie!

Mają własny, specjalny stos lokalny dla wątków.
Zastrzeżenie: Boost.Exception przerywa to, aby robić fajne rzeczy i dodawać szczegóły wyjątków po zakończeniu konstrukcji. Ale to jest hakerstwo!

Lekkość wyścigów na orbicie
źródło
Czy mógłbyś to rozwinąć Exception objects live in their own memory space? Czy masz dobrą lekturę, aby zasugerować na ten temat?
Richard Dally
@LeFlou: Mógłbym wskazać wam standard, ale byłoby trochę mylące, gdybyśmy uznali, że „dobra lektura” ...: P
Wyścigi lekkości na orbicie
Zdecydowanie tak, byłoby interesujące dowiedzieć się więcej na ten temat ze standardowego punktu widzenia. Czytam raport techniczny dotyczący wydajności C ++ , czy masz bardziej odpowiedni dokument?
Richard Dally,
@LeFlou: Cóż, nie staje się bardziej autorytatywny niż sam standard ...
Wyścigi lekkości na orbicie
1
@RichardDally sprawdź C ++ Primer 5th , § 18.1.1 Excpetion Object. Mówi, że obiekt wyjątku znajduje się w przestrzeni zarządzanej przez kompilator, co gwarantuje, że będzie dostępny dla każdego wywoływanego catch. Obiekt wyjątku jest niszczony po całkowitym obsłużeniu wyjątku.
Rick,
5

Mówi kompilatorowi, że nie będziesz wywoływał żadnej funkcji modyfikującej wyjątek, co może pomóc w optymalizacji kodu. Prawdopodobnie nie robi to dużej różnicy, ale koszt zrobienia tego jest również bardzo mały.

Warpin
źródło
2

czy zamierzasz zmodyfikować wyjątek? jeśli nie, to równie dobrze może być const. Z tego samego powodu, dla którego POWINIENEŚ używać const gdziekolwiek indziej (mówię POWINNO, ponieważ tak naprawdę nie robi to tak dużej różnicy na powierzchni, może pomóc kompilatorom, a także pomóc programistom w prawidłowym używaniu twojego kodu i nie robieniu rzeczy, których nie powinni)

programy obsługi wyjątków mogą być specyficzne dla platformy i mogą umieszczać wyjątki w zabawnych miejscach, ponieważ nie spodziewają się ich zmiany?

matowe
źródło
-1

Z tego samego powodu używasz const.


źródło
I z tego samego powodu, dla którego przedkładanie odniesień nad wskaźniki :-)
Dimitri C.
12
Proste i zręczne, ale nie do końca odpowiedź.
Omnifarious