Зачем ловить исключение как ссылку на const?


84

Я много раз слышал и читал, что лучше ловить исключение как ссылку на const, чем как ссылку. Почему:

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

лучше чем:

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

Ответы:


67

Тебе нужно:

  • ссылка, чтобы вы могли получить доступ к исключению полиморфно
  • константа для повышения производительности и сообщить компилятору, что вы не собираетесь изменять объект

Последнее не так важно, как первое, но единственная реальная причина для удаления const - это сигнализировать о том, что вы хотите внести изменения в исключение (обычно полезно, только если вы хотите повторно выбросить его с добавленным контекстом на более высокий уровень) .


1
«скажите компилятору, что вы не собираетесь изменять объект» - я полагаю, это может быть полезно, если вы передаете объект в качестве параметра при вызове функции.
Craig McQueen

1
что вы имеете в виду под «полиморфным доступом к исключению»?
манго

3
@mango предположительно означает возможность вызова виртуальной функции (например std::exception, what()функции). Если вы поймаете по значению, вы не сможете вызвать эту функцию и получить исходную информацию об исключении.
MM

11
посмотрел на сборку, созданную apple clang 7 и gcc 5 (с оптимизацией O3), и я не вижу никакой разницы между сборкой const ref и неконстантной ref. Итак, думаю, нет никакой разницы в оптимизациях для gcc и apple clang
Василий Сошников

2
Компилятор может легко увидеть, какие объекты вы изменяете, а какие нет ( SSA и постоянное распространение). Требуется лучшее объяснение (или это миф?).
rustyx

31

В принципе, нет никаких причин.

Объекты-исключения живут в собственном пространстве памяти поэтому вам не нужно беспокоиться о перехвате исключений, созданных во временных выражениях.

Все, что вы делаете, - это обещание, что вы не будете изменять объект исключения, но поскольку объекты исключения должны иметь неизменяемый интерфейс , на самом деле здесь нет ничего практичного.

Однако, когда вы ее читаете, вам может стать тепло и уютно - вот как это для меня!

У них есть свой собственный, специальный стек, локальный для потока.
Отказ от ответственности: Boost.Exception нарушает это, чтобы делать забавные вещи и добавлять детали исключения после создания. Но это же хакерство!


Не могли бы вы уточнить Exception objects live in their own memory space? Вы можете что-нибудь почитать по этому поводу?
Ричард Далли,

@LeFlou: Я мог бы указать вам на стандарт, но было бы немного ошибочно считать, что это «хорошее чтение» ...: P
Гонки легкости на орбите

Однозначно да, было бы интересно узнать об этом подробнее со стандартной точки зрения. Я читаю технический отчет о производительности C ++ , у вас есть более подходящий документ?
Ричард Далли

@LeFlou: Что ж, он не может быть более авторитетным, чем сам стандарт ....
Lightness Races in Orbit

1
@RichardDally проверьте C ++ Primer 5th , § 18.1.1 Excpetion Object. В нем говорится, что объект исключения находится в пространстве, управляемом компилятором, который гарантированно будет доступен для любого вызываемого улова. Объект исключения уничтожается после того, как исключение полностью обработано.
Рик

5

Он сообщает компилятору, что вы не будете вызывать какую-либо функцию, изменяющую исключение, что может помочь оптимизировать код. Наверное, не имеет большого значения, но и затраты на это очень небольшие.


2

вы собираетесь изменить исключение? в противном случае это также может быть const. по той же причине, по которой вы ДОЛЖНЫ использовать const где-либо еще (я говорю СЛЕДУЕТ, потому что на самом деле это не имеет большого значения на поверхности, может помочь компиляторам, а также помочь кодерам правильно использовать ваш код и не делать того, чего они не должны)

обработчики исключений, могут быть специфичными для платформы и могут помещать исключения в забавные места, потому что они не ожидают их изменения?


-1

По той же причине вы используете const.


И по той же причине, почему предпочитать ссылки указателям :-)
Dimitri C.

12
Простой и бойкий, но не совсем ответ.
Omnifarious
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.