Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Kgfq
74 / 37 / 2
Регистрация: 23.09.2012
Сообщений: 408
#1

try vs return в обработке ошибок - C++

15.11.2012, 23:04. Просмотров 680. Ответов 11
Метки нет (Все метки)

Скажите пожалуйста, как лучше обрабатывать ошибку:
return ...
или
throw ...
?

Если функция типа void

Добавлено через 13 минут
вверх

Добавлено через 12 минут
выше_
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.11.2012, 23:04
Здравствуйте! Я подобрал для вас темы с ответами на вопрос try vs return в обработке ошибок (C++):

Несколько ошибок при обработке строк - C++
Доброго времени суток. При тестировании обнаружил несколько проблем с обработкой строки. 1. не работает с русскими словами. (qwerty -...

В чем разница между return и return false/true - C++
Привет всем. Вот подскажите плиз) return; return false; return true; расскажите пожалуйста об етих операторах.. чем они...

Как сделать так, что если файл существует return true, если нет - return false - C++
Здравствуйте, я новичок в программировании. Мой вопрос очень прост: как сделать так, что если файл существует return true если нет return...

Пустая страница при обработке ошибок сервера - Java EE
Есть REST на: Java, Maven, TomCat, MySql, Hibernate. Сейчас делаю обработку ошибок сервера 404, 400 и т.д. В файле web.xml добавил: ...

"Ускорение" программы по обработке ошибок - C#
Пишу диплом и возникла маленькая проблема: есть программа, которая при вводе текста исправляет орфографию (была написана не мной)....

Что такое в jquery и java return false и return true - jQuery
Если я правильно понимаю, то return false отменяет действие по умолчанию, например клик по ссылке, а return true это наоборот приводит в...

11
diagon
Higher
1932 / 1198 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
15.11.2012, 23:27 #2
Ваш вопрос не совсем понятен.
Но, мое мнение - стоит избегать throw везде, где это только возможно. Так как ваша функция возвращает void, то вы можете спокойно изменить ее на int и возвращать код ошибки(либо 0, если все прошло успешно). Мне такой подход кажется намного лучшим, чем вариант с исключениями.
0
ForEveR
В астрале
Эксперт С++
7983 / 4742 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
16.11.2012, 00:04 #3
diagon, А аргументы? Сферическая скорость в вакууме? Не так давно читал статейку, где объяснялось, что исключения в С++ не такие уж дорогостоящие.
0
Kgfq
74 / 37 / 2
Регистрация: 23.09.2012
Сообщений: 408
16.11.2012, 00:15  [ТС] #4
ForEveR, при однократном вычислении, может и не очень. А что насчет БД?
0
OhMyGodSoLong
~ Эврика! ~
1244 / 993 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
16.11.2012, 02:20 #5
Это давний срач: коды возврата vs исключения.

Основное принципиальное отличие: поведение по умолчанию (если не писать дополнительного кода). Коды возврата по умолчанию игнорируются, исключения по умолчанию пробрасываются дальше. Детектор: если вы пишете кодами возврата и у вас довольно часто встречается что-то вида
C
1
2
3
4
err = doSomething();
if (!err) {
    return err; // или goto error_handling, где обработка / return err;
}
то подумайте над переходом к исключениям.

И наоборот, если у вас большая часть "опасных" мест завёрнута в try-блоки и в основном исключения не перебрасываются наверх или тупо игнорируется, то подумайте над переходом к кодам возврата.

Сферическая скорость в вакууме исключений — я думаю, не медленее if (err) { return err; }. Пробежаться по стеку при пробросе наверх в любом случае придётся. Ну и помните: исключения для исключительных ситуаций. Не для штатных и ожидаемых ошибок, а для чего-то, что ставит под угрозу всю дальнейшую работу, так что скорость их работы не является критичной.

Добавлено через 47 минут
Проверил на тупом синтетическом примере
Кликните здесь для просмотра всего текста
C++
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <ctime>
#include <iostream>
#include <cmath>
 
const int NUM = 10000;
int SLOW;
 
int fail1(int i)
{
    {   double x = 1.0;
        for (int j = 1; j < SLOW; ++j) {
            for (int k = 1; k < SLOW; ++k) {
                x *= j;
                x *= k;
                x = sqrt(x);
            }
        }
    }
    if (i == 0) {
        return 1;
    }
    int err;
    err = fail1(i - 1);
    if (!err) {
        return err;
    }
    return 0;
}
 
int fail2(int i)
{
    {   double x = 1.0;
        for (int j = 1; j < SLOW; ++j) {
            for (int k = 1; k < SLOW; ++k) {
                x *= j;
                x *= k;
                x = sqrt(x);
            }
        }
    }
    if (i == 0) {
        throw 1;
    }
    return fail2(i - 1);
}
 
int main()
{
    clock_t start, end;
    for (int i = 1; i < 30; ++i) {
        SLOW = i;        
        start = clock();
        fail1(NUM);
        end = clock();
        std::cout << (end - start) << ",";
 
        start = clock();
        try {
            fail2(NUM);
        }
        catch(const int &v) {
            // empty
        }
        end = clock();
        std::cout << (end - start) << "\n";
    }
}
У меня при -O0 исключения раз в 20 тормознутее. -O1 — на ~10% тормознутее. -O2/-O3 — идут вровень с кодами возврата
0
alkagolik
Заблокирован
16.11.2012, 04:59 #6
Цитата Сообщение от diagon Посмотреть сообщение
Но, мое мнение - стоит избегать throw везде, где это только возможно.
ну что еще может сказать зараженный...
Цитата Сообщение от ForEveR Посмотреть сообщение
Не так давно читал статейку, где объяснялось, что исключения в С++ не такие уж дорогостоящие.
время конечно твоё, но реально мне тебя жаль, ты это время выбросил в мусор.
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Это давний срач:
ну как бэ да!

2автор, вызов возвращает значение (если ты не знал), это значение надо проверить на ошибки. Как-то так по существу. О с++ забудь, это мусор для головы.
0
diagon
Higher
1932 / 1198 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
16.11.2012, 08:59 #7
Цитата Сообщение от ForEveR Посмотреть сообщение
А аргументы?
Исключения сильно затрудняют проектирование. Чего стоят хотя бы контейнеры STL и стек, к примеру. Сколько сил было потрачено, чтобы сделать их безопасными с точки зрения исключений. Без исключений попросту проще жить.
Не зря же в google coding style отказались от них вообще.
0
ForEveR
В астрале
Эксперт С++
7983 / 4742 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
16.11.2012, 09:30 #8
diagon, Ничего они не затрудняют, если грамотно все делать. Я бы не сказал, что проще жить без исключений, как раз вот коды ошибок постоянно проверять в разы проблемнее. Впринципе OhMyGod все верно сказал.Ну и так, для чтива: http://lazarenko.me/tips-and-tricks/...nd-performance
0
Evg
Эксперт CАвтор FAQ
18374 / 6421 / 441
Регистрация: 30.03.2009
Сообщений: 17,813
Записей в блоге: 28
16.11.2012, 09:52 #9
Моё мнение, что исключения следует использовать только в тех случаях, когда делается многоуровневый выход (т.е. фактически сворачивается целая ветвь исполнения программы и делается откат).

Например, какой-нибудь парсер от языка программирования, который состоит из большого количества вызовов, в том числе и рекурсивных. Логика парсера построена на разбор корректного текста. При появлении ошибки (которая может быть на 50-м уровне вложенности относительно начала работы) следует выдать диагностическое сообщение и сделать throw, который будет пойман в точке запуска парсера и там парсер завершит работу с ошибкой.

В остальных случаях, когда ошибка конкретного вызова обрабатывается в точке вызова, то код становится читаемый и понятный. А когда множество разнородных ошибок пытаются поймать через catch в одном месте, то такое понять намного сложнее. Хотя это тоже будет оправдано, если весь этот ворох ошибок должен приводить к одному и тому же результату: аварийному завершению целой ветви программы

Ответ на поставленный ТС'ом вопрос однозначно нельзя дать в принципе. В каждом конкретном случае надо принимать конкретное решение.

Доводы про то, что throw-catch работает долго, вообще говоря, не состоятельные, т.к. ошибка - это по сути нештатная работа программы и потеря лишних сотых долей секунды никакой погоды не сделает

Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Детектор: если вы пишете кодами возврата и у вас довольно часто встречается что-то вида
C
1
2
3
4
err = doSomething();
if (!err) {
    return err; // или goto error_handling, где обработка / return err;
}
то подумайте над переходом к исключениям
На мой взгляд это очередная попытка оценить качество программы количеством букв. Я для себя давно уже выработал главный критерий в выборе того или иного варианта написания кода: понятность кода для читающего (в том числе и того, кто впервые видит программу). Отрезанный от контекста пример не может служить доводом в пользу того или иного решения

Добавлено через 1 минуту
Цитата Сообщение от ForEveR Посмотреть сообщение
как раз вот коды ошибок постоянно проверять в разы проблемнее
Это зависит от того, что ты пишешь. Программу-самоделку или пользовательский софт. Для пользовательского софта выдача "что-то пошло не так", очевидно, не канает
0
ForEveR
В астрале
Эксперт С++
7983 / 4742 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
16.11.2012, 10:00 #10
Evg, Ну почему же что-то пошло не так сразу... Функция перекодировки кода ошибки в сообщение понятное юзеру к примеру.
0
OhMyGodSoLong
~ Эврика! ~
1244 / 993 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
16.11.2012, 10:25 #11
Цитата Сообщение от Evg Посмотреть сообщение
Например, какой-нибудь парсер от языка программирования...

В остальных случаях, когда ошибка конкретного вызова обрабатывается в точке вызова...
Вот я что и говорю: есть нужда в пробросе ошибок по стеку вызовов до удалённого обработчика, потому что только он может обработать ошибку — исключения. Если уровень абстракции не мешает написать понятную обработку сразу на месте — коды возврата.

Цитата Сообщение от Evg Посмотреть сообщение
На мой взгляд это очередная попытка оценить качество программы количеством букв. Я для себя давно уже выработал главный критерий в выборе того или иного варианта написания кода: понятность кода для читающего (в том числе и того, кто впервые видит программу). Отрезанный от контекста пример не может служить доводом в пользу того или иного решения
Ну, да, пример немного сферический. Я просто к тому, что эти ифы с одним ретёрном не несут смысловой нагрузки для тех, кто читает код и появляются на каждом уровне. Тогда как исключения ставят catch только там, где реально можно (хотя бы частично) обработать ошибку. А finally, слава RAII, отрабатывает вообще автомагически. Если же ошибка обрабатывается сразу на месте, то что вагон try-catch, что switch по коду одинаково выглядят.
0
Evg
Эксперт CАвтор FAQ
18374 / 6421 / 441
Регистрация: 30.03.2009
Сообщений: 17,813
Записей в блоге: 28
16.11.2012, 12:26 #12
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Я просто к тому, что эти ифы с одним ретёрном не несут смысловой нагрузки для тех
А когда у тебя есть вызов функции, при этом сразу не видно, в каком месте "внизу" будет throw, и в каком месте "наверху" ловится catch - вот это полный пинцет для читающего. Т.е. на ровном месте требуется исследовать кучу исходников, чтобы понять, где и чего

Цитата Сообщение от ForEveR Посмотреть сообщение
Функция перекодировки кода ошибки в сообщение понятное юзеру к примеру
Перед этим ты писал, что "коды ошибок постоянно проверять в разы проблемнее", теперь вот пишешь, что ещё перекодировку. Я просто к тому, что если ты поймал локальную ошибку, то делай на неё реакцию локально, чтобы читающему было понятно. И пусть у тебя будет 10 if'ов, зато все на виду и сразу всё видно. Если ошибка глобально-фатальная - то пусть где-то сверху ловится через catch.

Тут проблема в том, что многие понимают ответ на поставленный ТС'ом вопрос, но нормально облачить это в словесную форму очень трудно, особенно чтобы это понимал человек с небольшим опытом работы
1
16.11.2012, 12:26
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.11.2012, 12:26
Привет! Вот еще темы с ответами:

Односвязный список - объясните, как работают return 0 и return 1 - C (СИ)
проверьте, пжлса, по комментариям правильно ли я поняла принцип работы программы. Объясните, как здесь работают return 0 и return 1. и...

How can to return value (return value; ) of javascript function to ASP ? - C# ASP.NET
How can to return value (return value; ) of javascript function to ASP ?

Как происходит передача значения после return 0 и почему после return ставится 0 - C (СИ)
#include &lt;stdio.h&gt; int power(int m, int n); /* тест функции power */ main() { int i; for (i = 0: i &lt; 10, ++i) ...

Do\while в return - PHP
Вот столкнулся с проблемкой: Цыкл do\while выводит мне все заголовки новостей, но не там где нужно. Не могу придумать как его результат...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.