LINUX.ORG.RU

Как вы используете std::error_code?

 


1

3

Как вы обычно это используете?

Передаете по ссылке?

void foo(..., std::error_code &e)

Или возвращаете значение?

std::error_code foo(...)
// Или так, потому что первый вариант не всегда удобен
std::variant<stuff, std::error_code> foo(...)

★★★★★

Последнее исправление: Meyer (всего исправлений: 2)

Передаю по ссылке.

std::variant<...> мало подходит для использования таким образом, и, если уж есть особо острое желание возвращать sum-тип, следует пользоваться Boost.Outcome или другими аналогами.

Siborgium ★★★★★
()

Не использую. Бросаю исключения.

pr849
()

Засунь std::error_code в исключение. Бросай. Не замусоревый тип возврата.

ox55ff ★★★★★
()
Ответ на: комментарий от zerhud

Исключения достаточно тяжелая штука. К тому же я сейчас пишу обертку над сишной библиотекой и вариант завернуть внутренние коды ошибок в std::error_code/std::error_category выглядит более правильным, чем бросать исключения на каждый чих.

Meyer ★★★★★
() автор топика

std::error_code содержит два поля - код ошибки и указатель на категорию ошибки.

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

alysnix ★★★
()
Ответ на: комментарий от alysnix

std::error_code содержит два поля - код ошибки и указатель на категорию ошибки.

Еще описание ошибки. К тому же никто не мешает завернуть в него какие-нибудь свои коды ошибок.

Meyer ★★★★★
() автор топика
Ответ на: комментарий от Meyer

мне как-то не запал этот error_code. это я встретил в работе в std::filesystem, и там передается ссылка на обьект.

но сам такой подход - универсальный класс error_code, спорный, поскольку ошибка по сути нетипизирована. можно совершить ошибку при ее обработке.

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

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

alysnix ★★★
()
Ответ на: комментарий от alysnix

Ну хз. Как минимум стандартные коды ошибок и сетевые могут пересекаться по значению, поэтому введение категории неплохой вариант.

hatred ★★★
()
Ответ на: комментарий от Meyer

Это проброс в категорию. Сам error_code это не хранит.

hatred ★★★
()

Я по-тупому, вариация первого типа: если передан объект для сохранения кода ошибки - заполняю. Если не передан - бросаю std::system_error с упакованным кодом.

Как реализовывать: через перегрузку или через «дефолтный» объект кода ошибки - детали.

Условно, если пользователь API положил болт на обработку, но ошибка возникла, то всё свалится в этом месте на обработке исключения дефолтным обработчиком. Если ожидается ошибка, тот же EAGAIN, то имеет смысл передать объект и обработать возврат.

Да, можно заглушить через try {} catch (...) {/*empty*/} или передать объект error_code и его не обработать, но… ищущий да обрящет!

hatred ★★★
()
Ответ на: комментарий от Siborgium

Boost.Outcome

Посмотрел, выглядит интересно и не зависит от остального буста.

Meyer ★★★★★
() автор топика

Никак, бросаем исключения. Не хватало в ЯВУ городить C-образную лапшу из прошлого века с обработкой кодов.

slovazap ★★★★★
()
Ответ на: комментарий от Meyer

Исключения достаточно тяжелая штука.

Когда исключения не кидаются, то тяжёлая штука - это как раз коды.

К тому же я сейчас пишу обертку над сишной библиотекой и вариант завернуть внутренние коды ошибок в std::error_code/std::error_category выглядит более правильным, чем бросать исключения на каждый чих.

От того кидаешь ли ты исключения или возвращаешь коды, число чихов вообще никак не меняется.

slovazap ★★★★★
()
Ответ на: комментарий от Meyer

что значит «тяжелая»? в некотором смысле исключения как раз легче. единственное, так это, как упомянули выше, не все коды ошибок ошибкой являются. но это уже проблема более высокого уровня.

по поводу чихов тоже не понял. писанины больше с проверкой кодов. как проверить, что все случаи обработаны? может где-то затисася вызов функции, у которого проверки нет. тут надо какой-то класс сделать, что если мол не вызван метод какой-то, то исключение бросает, или вобще terminate (и в результате будет код в духе auto result = foo(); result.check(); и если этот check не вызван, то terminate). с вариантом имхо очень тяжело использовать будет. там чекать не так просто, много писать.

zerhud
()
Ответ на: комментарий от hatred

тут надо определится что делать в таком случае. раз вызываешь асинхронный метод, то нужно понимать, что данных вобщем-то может и не быть. что делать в этом случае? возращать например пустой массив данных или еще как-то. как раз тут можно с помощью исключений отделить ошибку от не ошибки, чего в нижележащей абстракции сделать было нельзя потому что исключений не было и пришлось запихать ошибки и стандартную работу функции в одно и то же значение и создать код «ошибки» для не ошибки. (тут же еще нюанс: не везде это не ошибка, где-то как раз хочется исключение бросить, типа bad_alloc.)

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

zerhud
()
Ответ на: комментарий от zerhud

Относись к этому не как к коду ошибки, а как к статусному коду. Мир проще становится. У тебя просто статус такой: не ошибка, но данных нет. Значит нужно не просто крешнуться и расстроиться, а уйти куда-то в select/poll/epoll/etc и начать заниматься другими делами.

hatred ★★★
()
Ответ на: комментарий от zerhud

что значит «тяжелая»? в некотором смысле исключения как раз легче.

Мы про C++ говорим? Для разбегу: http://www.open-std.org/jtc1/sc22/open/n3646.pdf, раздел 2.4 Exception Handling. Там есть разные подходы, входу «Table» Approach, где у нас основной оверхед по времени (есть и другие: по куче, по размеру на диске) на выбрасывании исключения. Т.е. нужно строить архитектуру так, что бы исключение было реально исключительной ситуацией и случалось редко, иначе никакого high performance :-)

Ну и ещё чтива:

Есть в работе http://open-std.org/JTC1/SC22/WG21/docs/papers/2018/p0709r2.pdf, но там есть свои но.

hatred ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.