Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
Kgfq
74 / 37 / 2
Регистрация: 23.09.2012
Сообщений: 408
15.11.2012, 23:04     try vs return в обработке ошибок #1
Скажите пожалуйста, как лучше обрабатывать ошибку:
return ...
или
throw ...
?

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

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

Добавлено через 12 минут
выше_
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.11.2012, 23:04     try vs return в обработке ошибок
Посмотрите здесь:

C++ В чем разница между return и return false/true
C++ Return
Return C++
Как сделать так, что если файл существует return true, если нет - return false C++
return *this; C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
diagon
Higher
 Аватар для diagon
1920 / 1186 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
15.11.2012, 23:27     try vs return в обработке ошибок #2
Ваш вопрос не совсем понятен.
Но, мое мнение - стоит избегать throw везде, где это только возможно. Так как ваша функция возвращает void, то вы можете спокойно изменить ее на int и возвращать код ошибки(либо 0, если все прошло успешно). Мне такой подход кажется намного лучшим, чем вариант с исключениями.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
16.11.2012, 00:04     try vs return в обработке ошибок #3
diagon, А аргументы? Сферическая скорость в вакууме? Не так давно читал статейку, где объяснялось, что исключения в С++ не такие уж дорогостоящие.
Kgfq
74 / 37 / 2
Регистрация: 23.09.2012
Сообщений: 408
16.11.2012, 00:15  [ТС]     try vs return в обработке ошибок #4
ForEveR, при однократном вычислении, может и не очень. А что насчет БД?
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
16.11.2012, 02:20     try vs return в обработке ошибок #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 — идут вровень с кодами возврата
alkagolik
 Аватар для alkagolik
1510 / 616 / 79
Регистрация: 15.07.2011
Сообщений: 3,552
16.11.2012, 04:59     try vs return в обработке ошибок #6
Цитата Сообщение от diagon Посмотреть сообщение
Но, мое мнение - стоит избегать throw везде, где это только возможно.
ну что еще может сказать зараженный...
Цитата Сообщение от ForEveR Посмотреть сообщение
Не так давно читал статейку, где объяснялось, что исключения в С++ не такие уж дорогостоящие.
время конечно твоё, но реально мне тебя жаль, ты это время выбросил в мусор.
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Это давний срач:
ну как бэ да!

2автор, вызов возвращает значение (если ты не знал), это значение надо проверить на ошибки. Как-то так по существу. О с++ забудь, это мусор для головы.
diagon
Higher
 Аватар для diagon
1920 / 1186 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
16.11.2012, 08:59     try vs return в обработке ошибок #7
Цитата Сообщение от ForEveR Посмотреть сообщение
А аргументы?
Исключения сильно затрудняют проектирование. Чего стоят хотя бы контейнеры STL и стек, к примеру. Сколько сил было потрачено, чтобы сделать их безопасными с точки зрения исключений. Без исключений попросту проще жить.
Не зря же в google coding style отказались от них вообще.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
16.11.2012, 09:30     try vs return в обработке ошибок #8
diagon, Ничего они не затрудняют, если грамотно все делать. Я бы не сказал, что проще жить без исключений, как раз вот коды ошибок постоянно проверять в разы проблемнее. Впринципе OhMyGod все верно сказал.Ну и так, для чтива: http://lazarenko.me/tips-and-tricks/...nd-performance
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16821 / 5242 / 318
Регистрация: 30.03.2009
Сообщений: 14,118
Записей в блоге: 26
16.11.2012, 09:52     try vs return в обработке ошибок #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 Посмотреть сообщение
как раз вот коды ошибок постоянно проверять в разы проблемнее
Это зависит от того, что ты пишешь. Программу-самоделку или пользовательский софт. Для пользовательского софта выдача "что-то пошло не так", очевидно, не канает
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
16.11.2012, 10:00     try vs return в обработке ошибок #10
Evg, Ну почему же что-то пошло не так сразу... Функция перекодировки кода ошибки в сообщение понятное юзеру к примеру.
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
16.11.2012, 10:25     try vs return в обработке ошибок #11
Цитата Сообщение от Evg Посмотреть сообщение
Например, какой-нибудь парсер от языка программирования...

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

Цитата Сообщение от Evg Посмотреть сообщение
На мой взгляд это очередная попытка оценить качество программы количеством букв. Я для себя давно уже выработал главный критерий в выборе того или иного варианта написания кода: понятность кода для читающего (в том числе и того, кто впервые видит программу). Отрезанный от контекста пример не может служить доводом в пользу того или иного решения
Ну, да, пример немного сферический. Я просто к тому, что эти ифы с одним ретёрном не несут смысловой нагрузки для тех, кто читает код и появляются на каждом уровне. Тогда как исключения ставят catch только там, где реально можно (хотя бы частично) обработать ошибку. А finally, слава RAII, отрабатывает вообще автомагически. Если же ошибка обрабатывается сразу на месте, то что вагон try-catch, что switch по коду одинаково выглядят.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.11.2012, 12:26     try vs return в обработке ошибок
Еще ссылки по теме:

C++ return
с++ while return C++
C++ Несколько ошибок при обработке строк

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

Или воспользуйтесь поиском по форуму:
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16821 / 5242 / 318
Регистрация: 30.03.2009
Сообщений: 14,118
Записей в блоге: 26
16.11.2012, 12:26     try vs return в обработке ошибок #12
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Я просто к тому, что эти ифы с одним ретёрном не несут смысловой нагрузки для тех
А когда у тебя есть вызов функции, при этом сразу не видно, в каком месте "внизу" будет throw, и в каком месте "наверху" ловится catch - вот это полный пинцет для читающего. Т.е. на ровном месте требуется исследовать кучу исходников, чтобы понять, где и чего

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

Тут проблема в том, что многие понимают ответ на поставленный ТС'ом вопрос, но нормально облачить это в словесную форму очень трудно, особенно чтобы это понимал человек с небольшим опытом работы
Yandex
Объявления
16.11.2012, 12:26     try vs return в обработке ошибок
Ответ Создать тему
Опции темы

Текущее время: 12:38. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru