yigal_s: (Default)
[personal profile] yigal_s
1. Бытует мнение, что с exceptions программировать значительно сложнее, чем без них без них. Мол, exceptions привносят уйму новых проблем.
На самом деле, если абстрагироваться от мелких заморочек в С++, никаких новых проблем, не известных ранее, exceptions не привносят. По крайней мере, не привносят в то программирование, где не принято игнорировать возвращающиеся из вызова функций коды ошибок или выходить из функции по получении такого кода, не заботясь о консистентности данных.

2. 1991 год. Во втором издании книги "Язык программирование С++" Страуструпа, exceptions было посвящено всего 30 страниц. Всё выглядит просто и красиво.

3. Конец 1994 года. Я тогда прекрасно разбирался в exceptions. В тех самых тридцати страницах. В журнале "С++ Report" появляется статья "Exception handling: a false sence of security", автор которой признается, что, видимо, не способен написать exception-safe стек (!) Вслед за ним свою неспособность сделать это, видимо, должен признать и средний, а то и продвинутый программист С++ того времени.

4. 2000 год. Глава о безопасности исключений появилась только в виде приложения к третьему, специальному (как бы 3.1) изданию книги Страуструпа о С++. Целью этого приложения заявлялось, в частности "продемонстрировать эффективные методы построения exception safe и эффективных контейнеров". С тех пор как exceptions были введены в язык и до того времени, как создатель языка рассказал, как их использовать не в тривиальных школьных примерах, прошло девять лет.

1'. Снова пункт первый. Видимо, приходится признать, что подавляющее большинство программистского коммюнити С++ где-то до конца 90-х годов не умело и не знало, как правильно писать программы, корректно обрабатывающие ошибки (не важно, через исключения или через код возврата). Интересно, а как обстояли тогда дела в других языках? В Аda и Java, в отличие от С++, многое спасает наличие garbage collector-a. В Java, опять же, нет возврата объектов по значению, множественного наследования и хранения членов класса не по ссылке. Это устраняет многие проблемы, над которыми ломали и ломают себе голову программисты в С++, где всё перечисленное есть.

5. Конструкторы, которые C++ генерирует по умолчанию, включая конструктор копирования являются exception-safe. А вот генерируемый по умолчанию оператор присваивания таковым не является. Пример - оператор присваивания для класса, наследующегося напрямую от двух других, операторы присваивания которых способны кидать исключения. Можно ли в этом случае написать безопасный оператор присваивания вручную? Один гениальный человек, с которым мне довелось познокомиться, в 1999 году уверял меня, что сделать это вообще невозможно. А может быть, он просто не хотел говорить о существовании решения этой задачи во время job-интервью? :-)

6. Кошмар exception-safe - это попытаться правильно написать exception-safe функцию Swap для произвольного типа, взяв за основу то, как её пишут в обычном коде:
void Swap(T &t1, T &t2)
{

T temp=t1; // ok to throw
t1 = t2; // ok to throw - если эта функция кинет исключение, её обязанность оставить значение t1 как было
try {

t2 = temp;
}
catch(...)
{

// восстанавливаем старое значение
t1 = temp; // and what if this line throws??? :-(

}

}

7. Но именно в правильном дизайне этой функции лежит ключ к exception-safe программированию на С++.

8. Парадигма "Resource Acquisition Is Initialization", описанная Страуструпом во втором издании, зачастую удобна. Однако, увлечение ею привело к тому, что в С++ не был введён оператор try-finally. Если кое-кто полагает, что откатывать какую-то функциональность так уж удобно через деструкторы, следут его спросить, почему же тогда никому не приходит в голову программировать эту функциональность в конструкторах? Поговаривают, что когда-нибудь try-finally оператор будет введен в стандарт языка, дабы не отпугивать любителей Java и С#. Возможно, тогда мне тоже захочется написать что-нибудь с использованием exceptions.

9. А кабы зло бы всё пресечь, и получить транзакционную семантику языка забесплатно, а не через какие-то операторы finally, деструкторы и кропотливую ручную откатку каждого чиха, надо запретить оператор присваивания.

Date: 2007-01-30 08:23 pm (UTC)

Date: 2007-08-08 07:32 pm (UTC)
From: [identity profile] dumalkin.livejournal.com
Transactional memory - next silver bullet :)

Date: 2007-10-30 01:39 pm (UTC)
From: [identity profile] aamonster.livejournal.com
(тоскливо вздохнул)
И ведь хочется хотя бы частично на такую семантику уйти. А код с присваиваниями (пока что нужный для эффективности) изолировать.