Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/6: Рейтинг темы: голосов - 6, средняя оценка - 4.50
74 / 37 / 3
Регистрация: 23.09.2012
Сообщений: 408

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

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

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

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

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

Добавлено через 12 минут
выше_
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
15.11.2012, 23:04
Ответы с готовыми решениями:

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

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

XNet - получить тело запроса в обработке ошибок
Привет. В документации xNet запрос с обработкой ошибок примерно такой: try { using (var request = new HttpRequest()) {...

11
Higher
 Аватар для diagon
1953 / 1219 / 120
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
15.11.2012, 23:27
Ваш вопрос не совсем понятен.
Но, мое мнение - стоит избегать throw везде, где это только возможно. Так как ваша функция возвращает void, то вы можете спокойно изменить ее на int и возвращать код ошибки(либо 0, если все прошло успешно). Мне такой подход кажется намного лучшим, чем вариант с исключениями.
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
16.11.2012, 00:04
diagon, А аргументы? Сферическая скорость в вакууме? Не так давно читал статейку, где объяснялось, что исключения в С++ не такие уж дорогостоящие.
0
74 / 37 / 3
Регистрация: 23.09.2012
Сообщений: 408
16.11.2012, 00:15  [ТС]
ForEveR, при однократном вычислении, может и не очень. А что насчет БД?
0
~ Эврика! ~
 Аватар для OhMyGodSoLong
1258 / 1007 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
16.11.2012, 02:20
Это давний срач: коды возврата 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
1599 / 622 / 113
Регистрация: 15.07.2011
Сообщений: 3,548
16.11.2012, 04:59
Цитата Сообщение от diagon Посмотреть сообщение
Но, мое мнение - стоит избегать throw везде, где это только возможно.
ну что еще может сказать зараженный...
Цитата Сообщение от ForEveR Посмотреть сообщение
Не так давно читал статейку, где объяснялось, что исключения в С++ не такие уж дорогостоящие.
время конечно твоё, но реально мне тебя жаль, ты это время выбросил в мусор.
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Это давний срач:
ну как бэ да!

2автор, вызов возвращает значение (если ты не знал), это значение надо проверить на ошибки. Как-то так по существу. О с++ забудь, это мусор для головы.
0
Higher
 Аватар для diagon
1953 / 1219 / 120
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
16.11.2012, 08:59
Цитата Сообщение от ForEveR Посмотреть сообщение
А аргументы?
Исключения сильно затрудняют проектирование. Чего стоят хотя бы контейнеры STL и стек, к примеру. Сколько сил было потрачено, чтобы сделать их безопасными с точки зрения исключений. Без исключений попросту проще жить.
Не зря же в google coding style отказались от них вообще.
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
16.11.2012, 09:30
diagon, Ничего они не затрудняют, если грамотно все делать. Я бы не сказал, что проще жить без исключений, как раз вот коды ошибок постоянно проверять в разы проблемнее. Впринципе OhMyGod все верно сказал.Ну и так, для чтива: http://lazarenko.me/tips-and-t... erformance
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
16.11.2012, 09:52
Моё мнение, что исключения следует использовать только в тех случаях, когда делается многоуровневый выход (т.е. фактически сворачивается целая ветвь исполнения программы и делается откат).

Например, какой-нибудь парсер от языка программирования, который состоит из большого количества вызовов, в том числе и рекурсивных. Логика парсера построена на разбор корректного текста. При появлении ошибки (которая может быть на 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
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
16.11.2012, 10:00
Evg, Ну почему же что-то пошло не так сразу... Функция перекодировки кода ошибки в сообщение понятное юзеру к примеру.
0
~ Эврика! ~
 Аватар для OhMyGodSoLong
1258 / 1007 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
16.11.2012, 10:25
Цитата Сообщение от Evg Посмотреть сообщение
Например, какой-нибудь парсер от языка программирования...

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

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

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

Тут проблема в том, что многие понимают ответ на поставленный ТС'ом вопрос, но нормально облачить это в словесную форму очень трудно, особенно чтобы это понимал человек с небольшим опытом работы
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
16.11.2012, 12:26
Помогаю со студенческими работами здесь

При обработке ошибок с ExceptionMapper(Jersey), не получаю JSON
был создан класс-обработчик ошибок, чтобы можно было бросать в нужном месте exceptions типа RuntimeException. Во время выброса такого...

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

Что это isOk(int s),setAge(int g){if(isOk(g){age=g;return true;}else{.;return false;}}.getName(){return name;}?
package com.company; import java.io.Serializable; public class person implements Serializable { protected String name; ...

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

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


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а привычная функция main(). . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь(не выше 3-го порядка) постоянного тока с элементами R, L, C, k(ключ), U, E, J. Программа находит переходные токи и напряжения на элементах схемы классическим методом(1 и 2 з-ны. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru