Здравствуйте, Patalog, Вы писали:
P>Таких сценариев "просто не выполняет какую-то команду там дальше" исчезающе мало. Из моего опыта подходит только разбор какого-то сложного формата данных из недоверенного источника, при чем не просто разбор (с целью скажем показать картинку), а с целью анализа именно ошибок входных данных. P>Т.е. цель разбора\обработки является выдача результата проверки соответствия входных данных спецификации.
А я как раз наоборот очень редко встречаю ситуации, когда требуется именно "конец работы в случае ошибки" (а только в таких случаях исключения действительно эффективны и собственно для этого они и создавались). Вот случай ошибки выделения памяти... Потом помнится ещё была erlang-подобная модель потоков в C++ (когда порождённые потоки в случае любых ошибок молча умирали и перезапускались потом)... Ну и ещё пара случаев и собственно всё.
P>Прикол в том, что при таких сценариях работы "ошибки формата" перестают быть исключительными ситуациями, а становятся частью основной логики, т.е. об исключениях в терминах С++ речь уже не идет. =)
Ага, и я о том же. Только у меня класс ошибок, которые "перестают быть исключительными ситуациями" явно намного шире. )))
Здравствуйте, landerhigh, Вы писали:
L>Это один плагин. Читай внимательнее.
Да хоть бы и пять. Вот прикинь, нажимаю я в ворде "проверить орфографию", в документе у меня русский и пара английских ID, ворд значит не смог загрузить английский спеллер и такой вообще орфографию не проверяет, или, вовсе отгружается по terminate.
Правда зачётное западло?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, niXman, Вы писали:
X>Здравствуйте, MTD, Вы писали:
MTD>>1. Бородатые дядьки которые в начале 90-х попробовали С++ и обожглись, а теперь негативный опыт проецируют на сегодняшнее положение дел X>а что, в начале 90-ых, с исключениями в с++ было не так? X>(я тогда еще совсем сопливый был)
В Borland C++ и BCB до 5 версии, с исключениями был полный ахтунг. BCB5, на серьезном проекте, тоже под занавес отупел (бинарник валился при обработке исключения).
Что касается вообще плюсов, то на мой субъектный взгляд, только после появления VS2005 стало не страшно писать "по-настоящему интересные программы"
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Что касается вообще плюсов, то на мой субъектный взгляд, только после появления VS2005 стало не страшно писать "по-настоящему интересные программы"
Вообще забавна вся эта возня вокруг шаблонов, исклюений и прочих "тру-С++" фич, которые заработали-то без году неделя, и в старых больших проектах использовались ограниченно, а в новых ещё не накоплен опыт поддержки кода хотя бы в течении десятка лет...
IMHO, ещё не выработаны правильные подходы и оценки, и сами "тру-С++-фичи" тоже ещё будут меняться, пока не станут удобными и юзабельными без ограничений.
Хотя я исключения обычно использую, но не совсем так, как учат нас мэтры исключитеного-с-плюс-плюсения, но если есть какие-то причины этого не делать, то не использую без особых проблем, тоже...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, jazzer, Вы писали:
J>>Т.е. предполагается, что move-конструктор может бросить исключение? И нафига он такой нужен, если он фактически убивает оба объекта? E>Почему нет?
Т.е. осмысленных причин нет?
J>>В обоих случаях не будет утечек и все инварианты будут выполнены. E>Ну вот и приведи код, и мы потом его сравним с кодом, который без гарантий, насколько сложнее оно, проще и т. д...
Начнем с того, что у класса, который не обеспечивает базовой гарантии, даже деструктор нельзя звать — инварианты-то нарушены, а значит, деструктор может сделать все, что угодно, расстрелять любую память, позвать деструкторы дважды и т.п. В отсутствии базовой безопасности поведение программы при вылете исключения в общем случае неопределено, ее даже грохнуть корректно нельзя.
И ты говоришь: А давай код, который делает хз что и может отформатировать винчестер, сравним с кодом, который сделает все правильно, и посмотрим, что проще.
Типа а давай сварим суп из всех найденных грибов, и сравним его сложность с супом из только съедобных грибов.
Сравнивать, конечно, можно, но только смысла в этом ноль.
Но раз уж ты так просишь — вот (пишу прямо в браузере, не компилировал):
void reserve(size_t new_capacity)
{
char* old_buf = buf_;
buf_ = new char[new_capacity*sizeof(T)];
capacity_ = new_capacity;
const size_t orig_size = size_;
// в конце в любом случае прибьем old_buf со всем содержимым
on_scope_exit( [=]{
for (size_t i=0; i<orig_size; ++i) ((T&)( old_buf[i*sizeof(T)] )).~T();
delete[] old_buf;
});
// попробуем покопировать, нехай исключения летятfor (size_=0; size_<orig_size; ++size_)
new (&buf_[size_*sizeof(T)]) T(std::move( (T&)old_buf[size_*sizeof(T)] ));
}
Давай теперь то же на кодах возврата. Особенно сексуально будут выглядеть коды возврата из конструктора неизвестного типа и их смешение с ошибкой выделения памяти для буфера.
E>Ну тогда покажи то же но про два параллельных массива, например...
это еще что? У тебя развлечение такое — мне задания на кодинг выдумывать?
E>>>Для неё как будем сильную безопасность обеспечивать?.. J>>Так же E>В смысле "так же"? Ты код давай.
Замени А на Б в коде.
J>>Мы вроде про obfuscate говорили, не? А не про расход памяти и т.п? E>Ну, если нам на производительность плевать, то на кой нам вообще С++? Шарп и вперёд и с песнями о том, что память больше не ресурс...
Ты не подменяй тему обсуждения, а... Речь шла о том, что код становится запутанным — я показал, что не становится.
Если хочешь обсудить оптимизацию и как она влияет на понятность кода — я готов. Заодно расскажешь, как замечательно делается аналогичная оптимизация на кодах возврата.
J>>Но если ты хочешь оптимизировать, то придется забыть о концептуальной чистоте кода — оптимизированные решения почти всегда выглядят на порядок сложнее, чем наивный неоптимизированный код. Duff's device будет хорошим примером.
E>1) Duff's device на сегодня является писсимизацией.
Только лишь потому, что его встроили в кодогенератор. Есть еще куча приемов оптимизации, которые в кодогенератор не встроены. И все они не могут похвастаться простотой кода из школьного учебника. Так что сути это не меняет.
E>2) Ничего клнцептуально сложного в нём, тем не менее нет, гарантии безопасности -- зна-а-а-ачительно сложнее концептуально
Да что ты говоришь. Убрать за собой в случае вылета исключения — это же так сложно.
E>Последнее, но главное) Мы собственно уже моем считать, что я тебя убедил, что концепуально чистый прямой код на кодах возврата ЭФФЕКТИВНЕЕ такого же на исключениях? E>И при этом ещё и использует более простые концепции?
Самая простая концепция — вообще забить на любую обработку ошибок. Текст программы становится ну просто загляденье. И никаких гарантий — в точности то, что ты хочешь
E>{hr]Я не являюсь противником использования исключений. Но я являюсь противником концепции базовой гарантии безопасности. IMHO, она слишком оторвана от реальности и вообще нелогична.
Почему она вдруг оторвана от реальности и нелогична? Так трудно убрать за собой? С кодами возврата этого делать не нужно?
Базовая — это просто уборка за собой и приведение программы в минимально рабочее состояние.
Сильная — это транзакции, надеюсь, их ты не будешь оторванными от жизни называть, а то я тебя в http://rsdn.ru/forum/db/ отправлю.
E>Но это таки отдельный хитрый разговор.
Велкам.
как я понял, таки нет ни одного аргумента(для прикладного софта [1]) почему не нужно использовать исключения.
может быть, кто-то соизволит зарезюмировать сабж, и запечатлеть его в веках? (в блоге, или создать тему на форуме в режиме read-only)
[1]
для микроконтройлеров — размер бинаря увеличивается.
для компилятор с SJLJ — создается незначительный ран-тайм оверхед, который скорее является оправданием.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, Шарль Ожье де Бац де Кастельмор, Вы писали:
ioj>Вы ( не вы лично, а все сторонники исключений в этом треде) вообще читаете что в гугловском документе написано?
Но решение было сделано на основе другого фактора:
"On their face, the benefits of using exceptions outweigh the costs, especially in new projects. However, for existing code, the introduction of exceptions has implications on all dependent code. If exceptions can be propagated beyond a new project, it also becomes problematic to integrate the new project into existing exception-free code. Because most existing C++ code at Google is not prepared to deal with exceptions, it is comparatively difficult to adopt new code that generates exceptions."
Здравствуйте, jazzer, Вы писали:
ioj>>К тому же в С++ нет finally J>И очень хорошо, что нету. Оставим finally недоязыкам типа Java, у которых нет RAII.
The compositional properties of RAII, however, differ significantly from scope bound resources in that it allows for full encapsulation of the resources behind an abstraction. With the dispose pattern for resource management, "being a resource" becomes a property that is transitive to composition. That is, any object that is composed using a resource that requires resource management effectively itself becomes a resource that requires resource management.
Здравствуйте, niXman, Вы писали:
X>[1] X>для микроконтройлеров — размер бинаря увеличивается.
Это может влиять, но, как правило, у них достаточно ROM/флеша для рамзещения таблиц.
Что точно влияет — это то, что компилятор может не поддерживать исключений. Потому что их туда не позаботились добавить. Да и не нужны они там обычно, КМК — в исключительной ситуации там проще перезагрузиться
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, rusted, Вы писали:
R>>А можно посмотреть пример объекта, у которого move-конструктор кидает исключения? Желательно с пояснением зачем там кидание и зачем вообще в таком случае пользоваться move-семантикой. Это не троллинга ради, я действительно с ходу не смог нафантазировать такого примера и теперь меня мучает любобытство.
E>Ну, например, можно представить себе объект все действия с которым логгируются... E>Или можно представить себе конструктор перемещения, который чем-то вроде assert'а кидающего logic_error, проверяет валидность перемещаемого объекта...
А если съесть еще этих мягких французских грибов, то можно себе вообще такого напредставлять!
Если объект уже существует — он по определению валиден. Не говоря уже о том, что проверять валидность объектов при перемещении — это несколько, какое бы подобрать слово, retarded.
E>Но в целом это не важно. E>Я же просил просто пример функции написать, раз это так просто всё якобы.
Любая тема по обусждению RAII всегда скатывается в идиотизм с деструктором, кидающим при невозможности закрыть файл.
То, что ты хочешь — это словесный онанизм примерно того же плана.
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, landerhigh, Вы писали:
L>>Нет. Я не понимаю, зачем это в принципе нужно пытаться сделать. Могу предложить ради разнообразия еще траву покосить в противогазе — занятие примерно одного рода по осмысленности.
E>И как трава? Забористая?
L>>Это один плагин. Читай внимательнее.
E>Да хоть бы и пять. Вот прикинь, нажимаю я в ворде "проверить орфографию", в документе у меня русский и пара английских ID, ворд значит не смог загрузить английский спеллер и такой вообще орфографию не проверяет, или, вовсе отгружается по terminate.
Сдуру можно и horseraddish сломать, чо. Только к теме отношения не имеет.
E>Правда зачётное западло?
Закономерное следствие засилия индустрии специалистами по взвешиванию гномиков боингами.
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, landerhigh, Вы писали:
L>>Неправильный Вы форум выбрали для вопросов о скрещивании ежей с ужами, коллега E>Я верно понимаю, что ты не знаешь как это селать просто?..
Вообще-то я знаю могу доказать очевидное в три строчки, что в общем случае кидающего move-конструктора в вакууме это сделать невозможно. А вот ты, похоже, этого так и не понял сюда просто потроллить пришел. И я тоже ничуть не удивлен.
Здравствуйте, jazzer, Вы писали:
J>Начнем с того, что у класса, который не обеспечивает базовой гарантии, даже деструктор нельзя звать — инварианты-то нарушены, а значит, деструктор может сделать все, что угодно, расстрелять любую память, позвать деструкторы дважды и т.п. В отсутствии базовой безопасности поведение программы при вылете исключения в общем случае неопределено, ее даже грохнуть корректно нельзя.
В смысле? конструктор обеспечивает базовую гарантию, деструктор обеспечивает некидание исключений. Что тут не так?
А сравнить я предлагаю с кодом, который сам по себе гарантий не обеспечивает...
J>
J>void reserve(size_t new_capacity)
J>{
J> char* old_buf = buf_;
J> buf_ = new char[new_capacity*sizeof(T)];
J> capacity_ = new_capacity; // обычно в векторе хранят не счётчик, а указатель за конец буфера, но это тут тонкости
J> const size_t orig_size = size_;
J> // в конце в любом случае прибьем old_buf со всем содержимым
J> on_scope_exit( [=]{
J> for (size_t i=0; i<orig_size; ++i) ((T&)( old_buf[i*sizeof(T)] )).~T();
J> delete[] old_buf;
J> });
J> // попробуем покопировать, нехай исключения летят
J> for (size_=0; size_<orig_size; ++size_)
J> new (&buf_[size_*sizeof(T)]) T(std::move( (T&)old_buf[size_*sizeof(T)] ));
J>}
J>
Это сейчас ещё даже во многих популярных боевых компиляторах не заведётся...
Может быть когда-нибудь, лет через пять-десять...
Но даже то, что написано тут мне не нравится категоррически, очень мутно и сложно.
Ну давай всё равно почитаем...
Ты, кажется, хотел разрушать в случае неудачи все данные, или все скопированные данные, я же не перепутал?
Тут, вроде как, делают что-то другое...
Скажем, если этот массив, окажется полем структуры из двух параллельных массивов, то уже будет немного неприятно. Прийдётся по любому исключению грохать содержимое обоих...
J>Давай теперь то же на кодах возврата. Особенно сексуально будут выглядеть коды возврата из конструктора неизвестного типа и их смешение с ошибкой выделения памяти для буфера.
Там не будет std::vector'а, там надо как-то иначе.
Например, у типа будет не конструктор перемещения, а перегруженная функция ERR_CODE move_array_item( T& dst, T& src ), которая вернёт, смогла или нет,..
точный аналог втоего кода тогда будет выглядеть как-то так:
ERR_CODE reserve( size_t new_capacity )
{
ERR_CODE res = EC_Ok; // это мантра ;)if( new_capacity <= capacity_ ) { // Этого у тебя не было, но положим, что ты про это забыл потому что код очень простой и понятный ;)return res;
}
assert( new_capacity > 0 );
// Создаём копию буфера, и передвигаем в неё данныеchar* extra_buf = new char[new_capacity*sizeof(T)] );
if( extra_buf == 0 ) {
return EC_MemoryError;
}
size_t cp_size = 0;
while( cp_size < size() && IsOk( res ) ) {
res = move_array_item( ((T*)extra_buf)[cp_size], ((T*)buf_)[cp_size] );
}
// тут мы ещё можем решить, что разрушать. Например, можно разрушать старый буффер только если полностью получилось скопировать новыйif( IsOk( res ) ) {
std::swap( extra_buf, buf_ );
std::swap( size_, cp_size );
capacity_ = new_capaciry;
}
while( cp_size > 0 ) {
( --cp_size + (T*)extra_buf )->~T(); // Разрушаю всё-таки с конца...
}
delete[] extra_buf;
return res;
}
длиннее, но проще. + учтено чуть больше всяких мелочей и содно выбрать что в случае аварии делаем.
Но это всё равно класс спректированный под исключения. Например, если мы вспомним, что ещё бывают всякие там insert и erase, которым надо сдвигать куски буфера, то у нас начнутся проблемы.
Либо нам надо будет написать походие циулы несколько раз. А всё потому, что мы не можем позволить себе иметь кусок памяти, где просто память и объекты перемешаны как попало...
Зато, если без исключений пишем, или пости без исключений, например, то можно функцию move_array_item сделать чуть прикольнее.
Типа такой:
template<typename T> ERR_CODE move_array_item( void* dst, T* src )
{
try {
::new T( std::move( *src ) );
src->~T();
} catch( ... ) {
return EC_CopyError; // или как-то ещё, как оно последовательно сделано в окружении без исключений -- отдельная песня.
}
return EC_Ok;
}
Ну и с этой инфраструктурой мы легко можем теперь писать разные штуки вроде insert...
Кстати, я так думал, что ты заведёшь внутри reserve ещё одну копию вектора, в котором зарезервируешь нужный буффер, потом перенесёшь элементы и обменяешь это всё.
E>>Ну тогда покажи то же но про два параллельных массива, например... J>это еще что? У тебя развлечение такое — мне задания на кодинг выдумывать?
Я пытаюсь тебе показать, что сохранять инварианты в случае исключения весьма небесплатно. И даже гарантировать отсутствие утечек не всегда просто.
J>Ты не подменяй тему обсуждения, а... Речь шла о том, что код становится запутанным — я показал, что не становится. J>Если хочешь обсудить оптимизацию и как она влияет на понятность кода — я готов. Заодно расскажешь, как замечательно делается аналогичная оптимизация на кодах возврата.
Во-первых, я не сторонник кодов возврата, я всего лишь понимаю люедй, которые не хотят связываться с исключениями, так что я могу исказить позицию тру сторонников.
Во-вторых, тему я не подменяю. Имелось же в виду "программы аналогичные по функционалу и эффективности", иначе смысла нет обсуждать. Ясен пень что и так и сяк можно написать просто, а можно сложно, можно эффективно, а можно неэффективно. Надо сравнивать эффективно и хорошо там и эффективно и хорошо там...
J>Только лишь потому, что его встроили в кодогенератор. Есть еще куча приемов оптимизации, которые в кодогенератор не встроены. И все они не могут похвастаться простотой кода из школьного учебника. Так что сути это не меняет.
Ну если речь про алгоритмические оптимизации, то обычно они от языка и использования исключений и т. п. мало зависят, хотя я знаю пример в пользу исключений, как раз
А если про затачивание кода под архитектуру, то обычно это танцы с бубнами вокруг формата данных, а не кода, так как такого рода оптимизации таки в кодогенераторах уже сидят почти везде...
E>>2) Ничего клнцептуально сложного в нём, тем не менее нет, гарантии безопасности -- зна-а-а-ачительно сложнее концептуально J>Да что ты говоришь. Убрать за собой в случае вылета исключения — это же так сложно.
Конечно сложно, так как
1) Вылет может произойти где угодно
2) "Где угодно" вернуться к инвариантам всех данных во всей программе может быть трудно, если вообще возможно.
А в это время может случиться какая-нибудь клизьма. Ну там деструктор какой-нибудь нежданно куда-то слазит, или ещё чего...
E>>Последнее, но главное) Мы собственно уже моем считать, что я тебя убедил, что концепуально чистый прямой код на кодах возврата ЭФФЕКТИВНЕЕ такого же на исключениях? E>>И при этом ещё и использует более простые концепции? J>Самая простая концепция — вообще забить на любую обработку ошибок. Текст программы становится ну просто загляденье. И никаких гарантий — в точности то, что ты хочешь
Почему? Писать везде if( IsOk( res ) ) res = следующая_часть_обработки( параметры ); так уж сложно?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, landerhigh, Вы писали:
L>А если съесть еще этих мягких французских грибов, то можно себе вообще такого напредставлять!
Бро! Трава в противогазе, теперь французские грибы. То, что ты не уважаешь синтертику -- это правильно. А вот то, что ты такой напряжный -- нет. Джа не оценит
L>Если объект уже существует — он по определению валиден. Не говоря уже о том, что проверять валидность объектов при перемещении — это несколько, какое бы подобрать слово, retarded.
Некоторые проверяют валидность при ВСЕХ операциях. Способствует надёжности кода, между прочим...
L>Любая тема по обусждению RAII всегда скатывается в идиотизм с деструктором, кидающим при невозможности закрыть файл.
Э-э-э, гиде тут RAII файл или деструктор?
L>То, что ты хочешь — это словесный онанизм примерно того же плана.
IMHO ты хочешь помыться...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, landerhigh, Вы писали:
L>>>Нет. Я не понимаю, зачем это в принципе нужно пытаться сделать. Могу предложить ради разнообразия еще траву покосить в противогазе — занятие примерно одного рода по осмысленности.
E>>И как трава? Забористая?
L>Откуда я знаю, какая у тебя на этот раз трава?
Разве этоя предлагал её в противогазе косить?..
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, landerhigh, Вы писали:
E>>Да хоть бы и пять. Вот прикинь, нажимаю я в ворде "проверить орфографию", в документе у меня русский и пара английских ID, ворд значит не смог загрузить английский спеллер и такой вообще орфографию не проверяет, или, вовсе отгружается по terminate. L>Сдуру можно и horseraddish сломать, чо. Только к теме отношения не имеет.
А разве ты что-то другое предлагал?..
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, landerhigh, Вы писали:
L>Вообще-то я знаю могу доказать очевидное в три строчки, что в общем случае кидающего move-конструктора в вакууме это сделать невозможно. А вот ты, похоже, этого так и не понял сюда просто потроллить пришел. И я тоже ничуть не удивлен.
Забавно. Докажи, потому, что я знаю, как написать...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, jazzer, Вы писали:
E>>Я не являюсь противником использования исключений. Но я являюсь противником концепции базовой гарантии безопасности. IMHO, она слишком оторвана от реальности и вообще нелогична. J>Почему она вдруг оторвана от реальности и нелогична? Так трудно убрать за собой? С кодами возврата этого делать не нужно? J>Базовая — это просто уборка за собой и приведение программы в минимально рабочее состояние. J>Сильная — это транзакции, надеюсь, их ты не будешь оторванными от жизни называть, а то я тебя в http://rsdn.ru/forum/db/ отправлю.
E>>Но это таки отдельный хитрый разговор. J>Велкам.
Лучше ветку как-то выделить тогда. Тут это какой-то злобный офтоп.
В общем и целом, мне не нравится что в базовой, что в строгой гарантии, то, что имея классы обеспечивающие заданный уровень гарантий, трудно писать агрегирующие или как-то иначе использующие их классы с тем же уровнем гарантий.
Мало того, обеспечение уровня гарантий трудноверифицируемо. Оно никак не тестируемо, и вычиткой тоже легко прощёлкать ошибку. То есть на этот уровень ещё и полагаться нельзя.
В результате имеем пессимизацию кода, за веру в то, что иключения будут обработанны корректно.
С другой стороны, если мы таки считаем, что исключения -- это таки ошибки, то есть их в нормальной программе не должно бы быть, то эти усилия становятся ещё более странными.
В целом мне представляется намного более разумным другой подход к исключениям.
Вводим такое понятие, как данные, которые находятся в состоянии, которое позволяет их корректно разрушить. Ну назовём это как-то удаляемость данных, например.
1) У нас есть ровно два сценария обработки исклбчений
1а) Ожидаемое исключение. Например -- пытаемся открыть файл, указанный пользователем и ждём файлового исключения если что.
В этом сценарии нам нежелательны утечки, но инварианты не особо-то и нужны. Всё что надо -- удаляемость данных. Типа попробовали открыть, не смогли -- ну всё ращзрушили и пошли дальше чего-то пробовать.
При этом ничего, кроме беспроблемной удаляемости и отсутсвия утечек не гарантируем. Это очень сильно проще обеспечить и провериить тоже.
1б) реальная ошибка. logic_error типа. Тут нам и утечки пофигу, на самом деле. Реальность такова, что раз уж у нас logic_error, то мы мало чему можем верить. Так что всё равно будем отгружать массово.
Или там не сразу отгружать, а по какому-то доп. ещё событию. Не важно. Важно что за отсутсвие утечек имеет смысл бороться в этом сценарии только если это просто. Усложнять код ради отсутствия утечек нет смысла.
Теперь делаем второй шаг.
Если у нас сценрий 1а, то мы всегда знаем чего ждём, где ждём зачем и почему, короче всё локально. И никак иначе.
Если у нас сценарий 1б, то мы перехватываем исключение только где-то наверху, на уровне запроса пользователя к системе. И нигде раньше.
Реакция на 1а -- корректная обработка.
Реакция на 1б -- дискард всего что там мы по запросу насоздавали + отказа от запроса. Ещё при этом, в зависимости от программы, мы можем и рестартануться.
при таком подходе возникает вопрос, а что делать с критичными к потери ресурсами?
Идея такая, что заводим статический менеджер таких ресурсов, и сообщаем ему о том, что мы начали обработку нового запроса. И всё, что надо не потерять регим там. по концу запроса либо ресурсы переводим на другой запрос, либо закрываем все, которые потерялись через менеджер.
имеем полный перечень открытых ресурсов, лог, и можем этим всем управлять централизованно.
При этом такая техника хорошо ещё и с пулами всякими дружит. То есть мы можем завести, например, аллокатор, нарожать на нём каких-то сложных данных, потом аллокатор грохнуть, а все зарегенные на него ресурсы освободить без муторной бегатни по деструкторам, которая долгая и не всегда тривиальная, к тому же.
при этом, если двигаться в каком-то примерно таком направлении, то мы не только получаем лучшую верифицируемость, поддерживаемость, концептуальнубю простоту и эффективность, но и можем намного легче отказаться от использования исключений вообще...
И я сильно подозреваю, что верный путь лежит примерно в этой стороне, так как общепринятые гарантии безопасности на самом деле выбраны произвольно и обе две являются избыточными, если мы всё-таки подразумеваем, что исключение -- это то, чего у пользователя случаться не должно...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, jazzer, Вы писали:
J>Почему она вдруг оторвана от реальности и нелогична? Так трудно убрать за собой? С кодами возврата этого делать не нужно?
Это просто эмоции, а не аргументация. Программирование -- деятельность прагматическая и целенаправленная. У всего должна быть цель. Какова цель "уборки за собой"? Так ли уж это надо/эффективно/актуально?
Как усилия по обеспечению этой уборки поднимают доходы компании? На сколько, опять же?
С третьей стороны, если судить по популярности С#, то "убирать за собой" таки трудно и редко оправданно, с точки зрения разработки ПО в рамках бизнеса
J>Сильная — это транзакции, надеюсь, их ты не будешь оторванными от жизни называть, а то я тебя в http://rsdn.ru/forum/db/ отправлю.
Ну это вообще особый случай. И я, если честно, ни за что не доверился бы СУБД, целостность которой гарантируется не архитектурными решениями на высоком достаточно уровне, а тем, что якобы все структуры данных в этой программе на всех уровнях обеспечивают строгую гарантию
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском