Обновить

Комментарии 11

Годнота! Добавил себе в закладки.
Запоздалая, но полезная статья.

От себя добавлю, что error_category::message не обязывает возвращать константную строку. Возможны прокси-категории, скажем, для группировки ошибок по типам, локализации, преобразования кодировок (привет Microsoft), конструирование сообщений на лету и многое другое.

Из-за того, что message возвращает std::string вместо const char*, пришлось отказаться от этого удобного способа обработки ошибок на микроконтроллере. Сильно напрягает по ресурсам, когда их мало.

все стандартные контейнеры позволяют переопределять аллокатор

И что это даст? Всё равно останется аллокация и копирование. А текст описания ошибки в подавляющем числе случает вполне себе вписывается в рамки const char*.

Недавно Andrzej Krzemieński опубликовал пару статей про создание собственных error_code и error_condition:
Your own error code
Your own error condition


На мой взгляд, там более понятно объясняется разница между ними.

Спасибо за наводку. Прочту на днях, как раз сам сейчас пытаюсь вникнуть во все тонкости темы.
Возможно, переведу и эти статьи. Или, быть может, уже кто-то перевел?

P.S.: Забавно, что этот автор тоже ссылается на переведенный здесь цикл.

Увы, у технологии есть и минусы:


  1. При сравнении error_code и error_condition делается минимум один виртуальный вызов, если они эквивалентны, и минимум два, если нет. Это дорого.


  2. В libstd++ (стандартная библиотека C++ на debian) между версиями 3.4.18 и 3.4.21 есть проблемы с совместимостью. Если такие два теста собрать на Ubuntu Trusty, а запустить на Ubuntu Xenial, первый выдаст неверный результат, а второй упадёт.

С такими минусами, в частности, столкнулись в LLVM и обходят их так:
https://github.com/llvm-mirror/llvm/commit/803fe1968007aa7a9c4f9674af648c9840f02a11
https://github.com/llvm-mirror/llvm/blob/master/include/llvm/Support/Errc.h

Согласен, технология дорогая. Но за удобство абстракций всегда приходится платить, верно?

А вот накладку в реализации стандартной библиотеке сложно относить к минусам именно самой технологии. Кстати, спасибо что поделились этой информацией, не находил упоминаний об этом ранее.
Лично мне кажется, что это не те абстракции, за которые я хотел бы платить. Мне вполне достаточно статического отображения платформозависимых кодов в платформонезависимые, и не каждый раз при каждом сравнении, а один раз, при первом их появлении. Дальше можно сравнивать коды по значению, писать `switch`-и и это будет дёшево.

Ситуаций, где мне потребовалось бы явно работать с платформозависимыми кодами вне платформенных обёрток, я стараюсь не допускать. Остаётся платформозависимое описание ошибки, которое нужно протащить через платформонезависимый код. Вот для него виртуальный вызов вполне адекватен, но и без него можно было бы просто протащить необрабатываемый char* (правда, его пришлось бы вычислять нелениво).

А сейчас я плачу в каждом сравнении, чтобы иметь возможность расширять категории ошибок в runtime, что мне за всю мою практику не понадобилось ни разу.

В одной из своих статьей Страуструп писал:
> In general, C++ implementations obey the zero-overhead principle: What you don’t use, you don’t pay for. And further: What you do use, you couldn’t hand code any better.

Для разработчиков LLVM и для меня это место так не выглядит. Но интересно было бы увидеть примеры активного расширения system_error в настоящих проектах (boost предлагать не надо).

Думаю, всё сильно зависит от частоты вызовов.

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

Скажем, "не удалось открыть файл" - если он там ожидается ВСЕГДА, и ошибка прямо относится к исключительным ситуациям (например, закончилось место на диске, или отвалилась сетевая шара) - трудно представить, когда в этой ситуации надо экономить такты. А если закончилась память - то там вообще "мы все падаем, аааа!"

В общем, всё зависит от того, что считать ошибками. Этот путь должен быть исключительно редким, тогда ничего экономить не нужно.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации