вот здесь у нас вышел небольшой спор по поводу исключений.
В связи с этим, есть примеры большого-среднего софта, написанного командой от 5 человек на С++ в "правильном exception-safe" стиле c грамотным применением исключений?
Или exception-safety и коммандный труд несовместимы, либо требуют слишком квалифицированных С++ программистов?
Долго думал над группой, решил всё-таки в С++.
Правильно работающая программа — просто частный случай Undefined Behavior
Re: С++ exception-safety, промышленное программирование и ка
_Winnie,
> вот здесь у нас вышел небольшой спор по поводу исключений. > В связи с этим, есть примеры большого-среднего софта, написанного командой от 5 человек на С++ в "правильном exception-safe" стиле c грамотным применением исключений?
Смотря что понимать под "правильным exception-safe стилем". Если речь идет об осознанном выборе тех или иных гарантий exception safety и последующей заботе об их выполнении, то да, примеры встречаются.
> Или exception-safety и коммандный труд несовместимы, либо требуют слишком квалифицированных С++ программистов?
К сожалению, корректная обработка "ошибочных" ситуаций в любом случае требует определенной квалификации, а без использования исключений -- еще и изрядно больших усилий.
Posted via RSDN NNTP Server 2.0
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[2]: С++ exception-safety, промышленное программирование и
Здравствуйте, Павел Кузнецов, Вы писали: ПК>_Winnie,
ПК>Смотря что понимать под "правильным exception-safe стилем". Если речь идет об осознанном выборе тех или иных гарантий exception safety и последующей заботе об их выполнении, то да, примеры встречаются.
Понимаю использование исключений вместо кодов возврата/GetLastError() и кучи if-ов, и так, что бы при этом не было мемориликов/падений программы из-за дважды вызванного деструктора/и тп.
>> Или exception-safety и коммандный труд несовместимы, либо требуют слишком квалифицированных С++ программистов?
ПК>К сожалению, корректная обработка "ошибочных" ситуаций в любом случае требует определенной квалификации, а без использования исключений -- еще и изрядно больших усилий.
Ну, я в том смысле что программист сам делает условные переходы, и видит где у него что не освобождается.
А видеть неявные переходы нужно привыкнуть. Техника "все освобождаем в деструкторах" помогает, но только в 98% случаев. У Саттера есть примеры очень хитрых утечек памяти. Например 90% "bycicle_hand_made_shared_ptr" не exception-safe, так как забывают освободить объект, если выделение памяти под счётчик кинуло исключение.
Правильно работающая программа — просто частный случай Undefined Behavior
Re[3]: С++ exception-safety, промышленное программирование и
Здравствуйте, _Winnie, Вы писали: _W>Здравствуйте, Павел Кузнецов, Вы писали: ПК>>_Winnie,
_W>Ну, я в том смысле что программист сам делает условные переходы, и видит где у него что не освобождается. _W>А видеть неявные переходы нужно привыкнуть. Техника "все освобождаем в деструкторах" помогает, но только в 98% случаев. У Саттера есть примеры очень хитрых утечек памяти. Например 90% "bycicle_hand_made_shared_ptr" не exception-safe, так как забывают освободить объект, если выделение памяти под счётчик кинуло исключение.
И, например, если я не прочитал бы об этом у Мейерса/Саттера, то я вряд ли бы об этом сам догадался. (например, о f(auto_ptr(new A), auto_ptr(new B))).
А сколько ещё таких закидонов, которые увидит глаз Саттера, а мой не увидит?
Правильно работающая программа — просто частный случай Undefined Behavior
Re[4]: С++ exception-safety, промышленное программирование и
Здравствуйте, Павел Кузнецов, Вы писали: ПК>_Winnie, >> А сколько ещё таких закидонов, которые увидит глаз Саттера, а мой не увидит?
ПК>А результат, который возвращает, скажем, [s][n]printf, ты/твои коллеги всегда проверяешь/ют?
Да, но memory-ликов от этого вроде не возникает.
s[n]printf не очень хороший пример, так как при неправильном format string программа просто UBится.
А IO ошибки printf безопасны. И зачастую правильной реакцией на них является игнорирование.
И сломавшийся printf — вещь теоретическая.
А вот от того, что из-за исключения в в одном файле у меня(у моего коллеги) не закроется другой файл и будут утечки памяти — это вещь практическая.
Правильно работающая программа — просто частный случай Undefined Behavior
Re[6]: С++ exception-safety, промышленное программирование и
Здравствуйте, _Winnie, Вы писали:
ПК>>А результат, который возвращает, скажем, [s][n]printf, ты/твои коллеги всегда проверяешь/ют? _W>Да, но memory-ликов от этого вроде не возникает.
"Да" в том смысле, что я согласен с тем, что не проверяют
Правильно работающая программа — просто частный случай Undefined Behavior
Re[6]: С++ exception-safety, промышленное программирование и
Здравствуйте, _Winnie, Вы писали:
ПК>>А результат, который возвращает, скажем, [s][n]printf, ты/твои коллеги всегда проверяешь/ют?
И если идёт о чём-то очень серьёзном, скажем о ядре OS, то там проверяется всё.
Правильно работающая программа — просто частный случай Undefined Behavior
Re[6]: С++ exception-safety, промышленное программирование и
Да, кстати, специфика у меня такая — невыгруженные из видеопамяти текстуры для меня фатальны, а вот то, что atoi не проверяет переполнения и никак не диагностирует ошибку — хрен с ним.
Правильно работающая программа — просто частный случай Undefined Behavior
Re[6]: С++ exception-safety, промышленное программирование и
_Winnie,
> ПК> А результат, который возвращает, скажем, [s][n]printf, ты/твои коллеги всегда проверяешь/ют?
> Да, но memory-ликов от этого вроде не возникает.
Memory leaks -- единственная или самая существенная неприятность, которая может произойти при обработке ошибочных ситуаций (вне зависимости от выбранного механизма)? В какой степени использование исключений изменяет вероятность получения memory leak? Какие техники ты применяешь без использования исключений для избежания memory leaks, и почему эти техники не помогают тебе в случае использования исключений?
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[7]: С++ exception-safety, промышленное программирование и
_Winnie,
> ПК>>А результат, который возвращает, скажем, [s][n]printf, ты/твои коллеги всегда проверяешь/ют?
> _W> Да, но memory-ликов от этого вроде не возникает.
> "Да" в том смысле, что я согласен с тем, что не проверяют
И это верно далеко не только для [s][n]printf, приведенного в качестве примера. Это я к тому, что отсутствие проблем, вызванных прерыванием потока исполнения исключениями приводит к другим проблемам. Ни те, ни другие не решаются сами собой, а нуждаются в строгой дисциплине со стороны программиста. В случае использования исключений у программиста появляется инструмент, позволяющий избавиться от значительного объема рутинных проверок, необходимых в случае работы с кодами возврата. Каждый выбирает для себя.
Posted via RSDN NNTP Server 2.0
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[7]: С++ exception-safety, промышленное программирование и
_Winnie,
> Да, кстати, специфика у меня такая — невыгруженные из видеопамяти текстуры для меня фатальны, а вот то, что atoi не проверяет переполнения и никак не диагностирует ошибку — хрен с ним.
В той же степени могут оказаться фатальными и попытки работать с каким-нибудь контекстом, если при его создании произошла проигнорированная ошибка.
Posted via RSDN NNTP Server 2.0
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[7]: С++ exception-safety, промышленное программирование и
_Winnie,
> ПК>>А результат, который возвращает, скажем, [s][n]printf, ты/твои коллеги всегда проверяешь/ют?
> И если идёт о чём-то очень серьёзном, скажем о ядре OS, то там проверяется всё.
Кстати, в "Философии" как раз сейчас подходящий топик идет. Вот приблизительное место кульминации на данный момент: http://rsdn.ru/forum/?mid=1512953
Будет ли в общем случае корректно работать данный код, если new будет возвращать 0 при нехватке памяти? (Не будет, т.к. в общем случае нет гарантий, что f ожидает нулевые указатели.)
Как его переписать, чтобы он работал корректно? (Вынести создание объектов в отдельные statements, снабдив соответствующими проверками.)
Какой недостаток получившегося корректного кода "с исключениями"? (Неграмотный программист может попытаться "упростить" его, приведя в первоначальный вид.)
Что с этим делать? (Имхо, нанимать грамотных программистов, т.к. неграмотные с тем же успехом "упростят" его и в случае отказа от исключений, и мы вернемся к началу данного сообщения.)
Posted via RSDN NNTP Server 2.0
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[8]: С++ exception-safety, промышленное программирование и
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>_Winnie,
>> Да, кстати, специфика у меня такая — невыгруженные из видеопамяти текстуры для меня фатальны, а вот то, что atoi не проверяет переполнения и никак не диагностирует ошибку — хрен с ним.
ПК>В той же степени могут оказаться фатальными и попытки работать с каким-нибудь контекстом, если при его создании произошла проигнорированная ошибка.
Вот, кстати, ловушка для VBScript-программеров. Конструкторы классов (в виде sub class_initialize()) не кидают исключения. Хотя глобальный объект err "взводится". В результате получаем недоделанный объект, который начинает брыкаться.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[5]: С++ exception-safety, промышленное программирование и
On Wed, 30 Nov 2005 02:11:19 -0000, Павел Кузнецов <5834@users.rsdn.ru> wrote:
> _Winnie, > >> А сколько ещё таких закидонов, которые увидит глаз Саттера, а мой не увидит? > > А результат, который возвращает, скажем, [s][n]printf, ты/твои коллеги всегда проверяешь/ют?
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>_Winnie,
>> f(auto_ptr(new A), auto_ptr(new B))
ПК>(Заранее прошу прощения за диалог с собой.)
ПК> Будет ли в общем случае корректно работать данный код, если new будет возвращать 0 при нехватке памяти? (Не будет, т.к. в общем случае нет гарантий, что f ожидает нулевые указатели.)
[...skipped...]
Если бы дело только этим ограничивалось Этот пример, имхо, из разряда проблем, которые могут произойти крайне редко.
Я вот вчера переделывал код, который работал приблизительно так:
void handle_trx( const some_trx_t & trx )
{
try
{
// Здесь проверяем возможность проведения транзакции.
// Если это не возможно, то исключения валятся именно здесь.
check_trx( trx );
// Транзакция запускается на выполнение.
initiate_trx( trx );
}
catch( const trx_handle_ex_t & x )
{
send_negative_response( trx );
}
catch( const std::exception & x )
{
// Все, произошло что-то непредвиденное.
log_unexpected_error( x );
// Ничего не предпринимаем, т.к. падать дальше не куда,
// а все ресурсы в этой точке должны быть освобождены.
}
}
void initiate_trx( const some_trx_t & trx )
{
// Сохраняем описание транзакции на будущее.
store_trx_info( trx );
// Передаем транзакцию конкретному исполнителю.
send_trx( trx );
}
В общем, спустя много времени после написания этого кода, я вижу в не несколько огрехов. Но заострить внимание хочу на функции initiate_trx(). Как оказалось, в нескольких случаях (при особых значениях некоторых полей в trx) исключения кидала функция send_trx(). Но уже после того, как информация о транзакции была сохранена! Т.е. транзакция никуда не ушла, но мы про нее помним. И по истечении тайм-аута можем возвращать не правильный результат (не правильный потому, что реально обработки транзакции не было). Следовало бы переписать initiate_trx() как-то так:
void initiate_trx( const some_trx_t & trx )
{
// Сохраняет описание транзакции в конструкторе.
store_trx_info_guard_t guard( trx );
send_trx( trx );
guard.commit(); // Если этого не сделать, то guard в деструкторе
// удалит описание транзакции.
}
Да только вот изначально это сделано не было (даже не помню уже почему), а со временем вылезло.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re: С++ exception-safety, промышленное программирование и ка
_W>Долго думал над группой, решил всё-таки в С++.
Оба варианта не правильные, это вопрос организации работы группы. Просмотра кода, определения политик кодировани, где какие и почему исключения должны использоваться, итп... Без этих мер грабли будут и просто с возвратом кодов ошибок.