Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
exception-safe код
|
|||
|---|---|---|---|
|
#18+
Привет, народ! Тема обширная, понимаю, но хотя бы азы затронуть интересно. В частности, Код: plaintext 1. 2. 3. 4. 5. 6. Допустим, a=b бросит исключение (в операторе присваивания), получается, что в a уже записали результат, в b - нет. Как гарантировать, что swap либо не выполнится вообще, либи полностью? Гуглил, нашел какие-то невнятные примеры со спецификацией исключений (которая не везде работает, и тот же Саттер не рекомендует ею вообще пользоваться). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.09.2013, 20:37 |
|
||
|
exception-safe код
|
|||
|---|---|---|---|
|
#18+
TimeCoder, То чего вы хотите добиться называется "сильной гарантией безопасности по исключениям". Во-первых вам нужно понять нужно ли это вообще, так как затратно. Возможно хватит и "слабой". (Поищите статью David Abrahams по сабжу, а так же есть глава из книжки Страуструпа, после прочтения этих двух источников все станет ясно). Чтобы добиться "сильной гарантии" нужно чтобы любые используемые операции (конструкторы всякие, присваивания, все все) давали сильную гарантию. Конструкторы и присваивание обычно дают сильную гарантию. Если же нет, а так же в вашем случае нужно заворачивать каждую строчку кода в try catch, и при возникновении исключения, отменять все вручную (для этого придется использовать временные переменные) и прокидывать его дальше вверх по стеку. Код: plaintext 1. Вообще сильную гарантию очень сложно достичь и часто не нужно. Например в приведенном выше коде, tmp_a = a; также может выбросить исключение. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.09.2013, 21:24 |
|
||
|
exception-safe код
|
|||
|---|---|---|---|
|
#18+
Семантику swap() практически всегда можно реализовать без бросания исключений. Для этого вместо присвоения через временую переменную надо swap сделать friend для класса, и прямо в ней рекурсивно вызывать swap для каждого поля. На самом нижнем уровне рекурсии будут готовые std::swap для встроенных типов которые и так не бросают исключений. Данный подход требует дополнительного допиливания если полях присутствуют ссылки друг на друга или на контейнеры. Правда эта же проблема есть и у исходного варианта :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.09.2013, 21:52 |
|
||
|
exception-safe код
|
|||
|---|---|---|---|
|
#18+
Anatoly Moskovsky, ну swap - просто как пример, даже если тут уйти от вызова конструктора копирования и оператора присваивания, в других случаях так не получится. Ну хотя бы реализация самого оператора присваивания: есть класс, в его полях могут быть другие составные типы, указатели, и нужно реализовать глубокую копию. Запросто может оказаться так, что на копировании одного из полей прилетит исключение, причем нам код того класса не доступен, и сделать его exception-safe мы не можем. Первой напрашивается идея sherzod_, оборачивать каждую операцию присваивания в try/catch, и если произошло - откатывать назад уже присвоенные. Но если при откате будут исключения (тоже ведь присваиваем) - то все, приплыли. Пишу, и по ходу такая идея пришла: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.09.2013, 08:05 |
|
||
|
exception-safe код
|
|||
|---|---|---|---|
|
#18+
TimeCoder, По спецификации исключений все, можно забыть навсегда. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.09.2013, 11:33 |
|
||
|
exception-safe код
|
|||
|---|---|---|---|
|
#18+
TimeCoder, По теме — моя первая мысль была, что же это за такое присваивание, что должно выбрасывать исключение? В присваивает слева валидный объект, и справа тоже валидный объект. Что может заставить присваивание выбросить исключение? На ум не приходит ничего, кроме нехватки памяти. Если очень большой объект справа, и очень мало памяти. Но в таких соцсетях и к копированию и swap относятся очень трепетно. В общем, данный пример надуман. В общем C++ не имеет механизмов решения такой проблемы. Но в частности, можно было бы сделать две копии объектов, a и b. И затем поймать исключение и вернуть все на начальную позицию. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.09.2013, 11:50 |
|
||
|
exception-safe код
|
|||
|---|---|---|---|
|
#18+
TimeCoder, Первой напрашивается идея sherzod_, оборачивать каждую операцию присваивания в try/catch, и если произошло - откатывать назад уже присвоенные. Но если при откате будут исключения (тоже ведь присваиваем) - то все, приплыли. так и что делать-то, это язык программирования, а не субд, он это не умеет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.09.2013, 11:54 |
|
||
|
exception-safe код
|
|||
|---|---|---|---|
|
#18+
TimeCoderAnatoly Moskovsky, ну swap - просто как пример, даже если тут уйти от вызова конструктора копирования и оператора присваивания, в других случаях так не получится. Ну хотя бы реализация самого оператора присваивания: есть класс, в его полях могут быть другие составные типы, указатели, и нужно реализовать глубокую копию. Запросто может оказаться так, что на копировании одного из полей прилетит исключение, причем нам код того класса не доступен, и сделать его exception-safe мы не можем. Первой напрашивается идея sherzod_, оборачивать каждую операцию присваивания в try/catch, и если произошло - откатывать назад уже присвоенные. Но если при откате будут исключения (тоже ведь присваиваем) - то все, приплыли. Пишу, и по ходу такая идея пришла: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. Почему тут не будет исключений — не понятно. Они могут быть. Использовать memcpy для копирования любых объектов нельзя, только POD. Тебе осталось сделать только ещё один шаг всего до правильного решения, но ты почему-то его не сделал. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.09.2013, 12:00 |
|
||
|
exception-safe код
|
|||
|---|---|---|---|
|
#18+
Код: plaintext 1. 2. 3. 4. 5. 6. 7. Но как уже сказали использовать memcpy для копирования объектов нельзя. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.09.2013, 12:12 |
|
||
|
exception-safe код
|
|||
|---|---|---|---|
|
#18+
MasterZivПо спецификации исключений все, можно забыть навсегда. Че это забыть? Есть noexcept (по сути тот же throw() ), которого вполне хватает. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.09.2013, 14:31 |
|
||
|
exception-safe код
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyMasterZivПо спецификации исключений все, можно забыть навсегда. Че это забыть? Есть noexcept (по сути тот же throw() ), которого вполне хватает. Ну и всё. Все спецификации. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.09.2013, 14:37 |
|
||
|
exception-safe код
|
|||
|---|---|---|---|
|
#18+
MasterZivНу и всё. Все спецификации. Так а больше все равно никто и не использовал, ну разве что дурачки какие ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.09.2013, 14:46 |
|
||
|
exception-safe код
|
|||
|---|---|---|---|
|
#18+
гм.. так а какой шаг? Для каждого поля данных вызвать std::swap ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.09.2013, 20:53 |
|
||
|
exception-safe код
|
|||
|---|---|---|---|
|
#18+
TimeCoderгм.. так а какой шаг? Для каждого поля данных вызвать std::swap ? именно! Ну и все swap и операторы и конструкторы перемещения должны быть noexcept. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.09.2013, 21:41 |
|
||
|
exception-safe код
|
|||
|---|---|---|---|
|
#18+
TimeCoderгм.. так а какой шаг? Для каждого поля данных вызвать std::swap ? Ну я лично имел в виду обратное присваивание в блоке catch. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.09.2013, 10:55 |
|
||
|
exception-safe код
|
|||
|---|---|---|---|
|
#18+
Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. http://www.cplusplus.com/reference/algorithm/swap/ ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.09.2013, 13:08 |
|
||
|
|

start [/forum/topic.php?fid=57&msg=38395779&tid=2019979]: |
0ms |
get settings: |
10ms |
get forum list: |
12ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
32ms |
get topic data: |
11ms |
get forum data: |
2ms |
get page messages: |
56ms |
get tp. blocked users: |
1ms |
| others: | 299ms |
| total: | 431ms |

| 0 / 0 |
