CXX95 Telegram 80
#story

Чем исключения в C++ похожи на сборщик мусора в других языках ♻️

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

Но когда возникает нужда что-то поправить в этой фиче, то программист замучается глотать пыль, копаясь в технической реализации. 🔍

Например, для Java и других языков со сборкой мусора это необходимость разбираться в алгоритмах сборки мусора (mark-and-sweep, etc.), в более хитрой работе с памятью чтобы сборщик собирал меньше мусора ("пул объектов"), понимать нужные настройки чтобы сборщик не фризил программу посередине HTTP-запроса, и так далее. Это все долго и нудно описывается в разных статьях.

В C++ есть подобная история с исключениями. Но здесь требуются еще более нетривиальные познания для полного понимания. Основных проблем две, первая встречается чаще, но вторая более жесткая:

1️⃣ Оверхед по времени исполнения и хуже с компиляторными оптимизациями. Есть супер крутой лонгрид Исключения C++ через призму компиляторных оптимизаций.

Вместо того, чтобы просто взять и вызвать функцию, которая теоретически может выбросить исключение, приходится делать дополнительный блок кода для обработки потенциального исключения, и переводить исполнение туда в случае исключения (лишняя проверка на КАЖДЫЙ вызов).

Также во многих оптимизациях исключения не участвуют. Например, оптимизация "удаление мертвого кода" считает, что код для обработки исключений нужен всегда, а там по транзитивности нужны и все переменные внутри него, и в итоге все вообще плохо оптимизируется.

2️⃣ Сложность в разработке, в том числе в обеспечении Strong Exception Guarantee.

Strong Exception Guarantee это гарантия, что если вызвать метод, который вдруг выбросит исключение, то состояние программы будет таким же, как было до вызова метода. Контейнеры по возможности реализуют SEG, и это очень муторно. В моей статье про контейнеры я описывал, когда работает SEG.

void TryAddWidget(std::vector<Widget>& widgets) {
// выполняем некий код...
Widget w;
try {
widgets.push_back(std::move(w));
} catch (...) {
// поймали исключение...
// ожидаем, что `widgets` остался юзабельным
}
}

В Стандарте есть велосипеды специально для SEG: std::move_if_noexcept.

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

Есть понятие гарантии Basic Exception Guarantee, программа продолжает работать, но данные немного поломаны. Например, в примере выше, в зависимости от свойств класса Widget, в векторе widgets могут стереться все элементы после выброса исключения 😐

Объяснение сути BEG на примере саппорта Microsoft Word (😢 - клиент, 🎧 - саппорт):

😢 - Это поддержка MS Word? Я писал книгу, но Word вдруг все удалил.
🎧 - Все нормально, просто мы предоставляем только базовые гарантии при ошибках программы.
😢 - Большое спасибо, удачного дня!

Во многих code style (например от Google) исключения использовать запрещено.

В компиляторах есть флаг -fno-exceptions, которые удаляют весь оверхед, связанный с исключениями, не генерируют лишний код. Исключения до сих пор можно будет бросать, но они просто будут крашить программу, и никак не будут обрабатываться.
Please open Telegram to view this post
VIEW IN TELEGRAM



tgoop.com/cxx95/80
Create:
Last Update:

#story

Чем исключения в C++ похожи на сборщик мусора в других языках ♻️

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

Но когда возникает нужда что-то поправить в этой фиче, то программист замучается глотать пыль, копаясь в технической реализации. 🔍

Например, для Java и других языков со сборкой мусора это необходимость разбираться в алгоритмах сборки мусора (mark-and-sweep, etc.), в более хитрой работе с памятью чтобы сборщик собирал меньше мусора ("пул объектов"), понимать нужные настройки чтобы сборщик не фризил программу посередине HTTP-запроса, и так далее. Это все долго и нудно описывается в разных статьях.

В C++ есть подобная история с исключениями. Но здесь требуются еще более нетривиальные познания для полного понимания. Основных проблем две, первая встречается чаще, но вторая более жесткая:

1️⃣ Оверхед по времени исполнения и хуже с компиляторными оптимизациями. Есть супер крутой лонгрид Исключения C++ через призму компиляторных оптимизаций.

Вместо того, чтобы просто взять и вызвать функцию, которая теоретически может выбросить исключение, приходится делать дополнительный блок кода для обработки потенциального исключения, и переводить исполнение туда в случае исключения (лишняя проверка на КАЖДЫЙ вызов).

Также во многих оптимизациях исключения не участвуют. Например, оптимизация "удаление мертвого кода" считает, что код для обработки исключений нужен всегда, а там по транзитивности нужны и все переменные внутри него, и в итоге все вообще плохо оптимизируется.

2️⃣ Сложность в разработке, в том числе в обеспечении Strong Exception Guarantee.

Strong Exception Guarantee это гарантия, что если вызвать метод, который вдруг выбросит исключение, то состояние программы будет таким же, как было до вызова метода. Контейнеры по возможности реализуют SEG, и это очень муторно. В моей статье про контейнеры я описывал, когда работает SEG.

void TryAddWidget(std::vector<Widget>& widgets) {
// выполняем некий код...
Widget w;
try {
widgets.push_back(std::move(w));
} catch (...) {
// поймали исключение...
// ожидаем, что `widgets` остался юзабельным
}
}

В Стандарте есть велосипеды специально для SEG: std::move_if_noexcept.

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

Есть понятие гарантии Basic Exception Guarantee, программа продолжает работать, но данные немного поломаны. Например, в примере выше, в зависимости от свойств класса Widget, в векторе widgets могут стереться все элементы после выброса исключения 😐

Объяснение сути BEG на примере саппорта Microsoft Word (😢 - клиент, 🎧 - саппорт):

😢 - Это поддержка MS Word? Я писал книгу, но Word вдруг все удалил.
🎧 - Все нормально, просто мы предоставляем только базовые гарантии при ошибках программы.
😢 - Большое спасибо, удачного дня!

Во многих code style (например от Google) исключения использовать запрещено.

В компиляторах есть флаг -fno-exceptions, которые удаляют весь оверхед, связанный с исключениями, не генерируют лишний код. Исключения до сих пор можно будет бросать, но они просто будут крашить программу, и никак не будут обрабатываться.

BY C++95


Share with your friend now:
tgoop.com/cxx95/80

View MORE
Open in Telegram


Telegram News

Date: |

Polls A new window will come up. Enter your channel name and bio. (See the character limits above.) Click “Create.” Healing through screaming therapy Clear ‘Ban’ on Telegram
from us


Telegram C++95
FROM American