2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу Пред.  1, 2, 3  След.
 
 
Сообщение10.02.2006, 18:26 


13/09/05
153
Москва
Цитата:
Как именно будет выглядеть проверка руками, если ошибки могут произойти:
1. Внутри Open - скажем, пароль не тот.
2. Внутри ExecuteReader - скажем, потерли таблицу.
3. Внутри Read - скажем, отвалилась сеть.
4. Внутри GetInt - скажем, тупой DBA забыл поставить NOT NULL на salary.
5. Внутри SendGreetings - скажем, лежит почтовый сервер.


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

 Профиль  
                  
 
 
Сообщение10.02.2006, 18:31 


13/09/05
153
Москва
ИМХО, обрабатывать ситуацию нужно там, где она появилась, а не валить все в кучу. И это можно сделать набором if'ов:) Все сводится к проектированию структуры классов и их взаимодействия, если грамотно спроектировать, то можно попробовать и без exception'ов обойтись.

 Профиль  
                  
 
 
Сообщение10.02.2006, 19:03 
Заслуженный участник


31/12/05
1517
VLarin писал(а):
Как именно будет выглядеть проверка руками, если ошибки могут произойти:
А как обычно программируются различные ситуации - проверили на наличие чего-нить, если косяк - что-нибудь сделали - if (!ошибка) то делаем что-то, а иначе идем дальше или возвращаем код ошибки.

Да, только мой код уже все это делает. А в какое спагетти он превратится после таких пяти проверок?

Далее, что делать с методом GetInt? Сейчас это функция, возвращающая int. Теперь ее придется превратить в функцию, возвращающую код ошибки, а само значение отдавать по ссылке. Значит, еще одна дополнительная переменная и две лишних строки кода, ПОМИМО проверок.

А что с Read? Он сейчас возвращает bool, показывающий, есть ли еще данные или кончились. Значит, придется возвращать код возврата и вместо while делать спагетти.

И что мы имеем в итоге? Вместо ясного короткого кода получится страшилище минимум на страницу, где нормальная работа постоянно перемежается с проверками на ошибки, которые еще наверняка где-нибудь забудут сделать. Попробуйте - увидите сами, я на такой код за пятнадцать лет уже насмотрелся достаточно. Ради чего создавать себе непреодолимые трудности, чтобы потом героически их преодолевать?

VLarin писал(а):
ИМХО, обрабатывать ситуацию нужно там, где она появилась, а не валить все в кучу.

Ситуация сетевого сбоя появилась в клиенте базы данных. Ее обработка в данной задаче заключается в добавлении определенной записи в лог программы. В какой-нибудь другой задаче - в выдаче сообщения на экран. Как именно клиент базы данных может это сделать в момент появления ситуации?

 Профиль  
                  
 
 
Сообщение10.02.2006, 19:16 


13/09/05
153
Москва
В некоторых задачах, да, я согласен, без использования исключений не обойтись, и/или с ними все можно чуть проще сделать. Я же про другое говорил - если грамотно спроектировать структруру классов, то можно попробовать и обойтись без них, вариантов решений много. Для простых задач, когда проще вернуть код ошибки, использовать исключения как-то слишком уж чрезмерно. А тем более в том, с чего началась эта дискуссия - проще сделать отложенную инициализацию и в ней что-нужно проверить.
На мой вгляд все сводится к взаимодействию объектов и тут возможно различные варианты поведения.

 Профиль  
                  
 
 
Сообщение10.02.2006, 19:21 
Заслуженный участник
Аватара пользователя


17/10/05
3709
:evil:
Ничто не бывает простым.

Обработка исключений заметно упрощает программу, особенно "культурно" написанную (auto_ptr, ...). Читать таку программу заметно проще, поскольку нужно отслеживать по сути только одну ветку. Кроме того, обработка ошибки по месту возникновения -- не всегда лучшая тактика, так как информация для членораздельной диагностики может быть просто не доступна в месте ошибки. (Пример -- класс, обварачивающий файл, с наворотами типа частичного разбора. Но он не знает, что разбирает, и правильно обработать ошибку не может.)

Обратной стороной медали является цена обработки исключений. Она не высока, она очень высока. Это приводит к полномум выключению исключений во многих встроенных приложениях. Кроме того, не все компиляторы правильно отслеживают исключения в многозадачном режиме. (Борюсь с соблазном сказать, что в однозадачном вообще программируют только студенты -- это не так :P . Но в однозадачном режиме проблем действительно на порядок меньше.)

 Профиль  
                  
 
 
Сообщение10.02.2006, 19:25 
Заслуженный участник


31/12/05
1517
VLarin писал(а):
Для простых задач, когда проще вернуть код ошибки, использовать исключения как-то слишком уж чрезмерно.

Про что я и говорю. Страуструп называет свой язык C++, но большинство программируют на C с классами - другом языке с тем же стандартом и той же библиотекой. Естественно, проект на MFC с исключениями стыкуется плохо. Если же у нас уже есть библиотеки, выбрасывающие исключения, точно так же естественно, что даже в простой задаче преобразовывать их обратно в коды возврата будет глупо.
VLarin писал(а):
все можно чуть проще сделать

Я уже продемонстрировал, во что выливается эта "чуть" :)
VLarin писал(а):
А тем более в том, с чего началась эта дискуссия

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

 Профиль  
                  
 
 
Сообщение10.02.2006, 19:31 
Заслуженный участник
Аватара пользователя


17/10/05
3709
:evil:
tolstopuz писал(а):
VLarin писал(а):
ИМХО, обрабатывать ситуацию нужно там, где она появилась, а не валить все в кучу.

Ситуация сетевого сбоя появилась в клиенте базы данных. Ее обработка в данной задаче заключается в добавлении определенной записи в лог программы. В какой-нибудь другой задаче - в выдаче сообщения на экран. Как именно клиент базы данных может это сделать в момент появления ситуации?

Одно из правил хорошего тона -- объект должен перевести себя в "безопасное" и предсказуемое состояние. И это очень существенно во многих системах. Отсутствие такового перехода было источником очень многих ошибок.

Хорошо, когда мы просто уничтожаем объект. А если нет? Не можем? И получается, что мы должны перехватить исключение в клиенте, сделать частичную обработку, и кинуть опять, на этот раз специфическое для клиента исключение.

Кроме того, в пользу такого подхода говорит еще и то, что в этом случае клиент БД может сделать свою запись в журнал, и что-то подобное. Это -- неоценимая помощь при разборе полетов. Отсутсвие же таковой "центра обработки" ведет к распылению информации по пользователям клиента БД, и может привести к маскировке реальной проблемы.

 Профиль  
                  
 
 
Сообщение10.02.2006, 19:44 
Заслуженный участник


31/12/05
1517
незванный гость писал(а):
Одно из правил хорошего тона -- объект должен перевести себя в "безопасное" и предсказуемое состояние. И это очень существенно во многих системах. Отсутствие такового перехода было источником очень многих ошибок.

Exception safety - наше всё, и RAII - пророк его.
незванный гость писал(а):
И получается, что мы должны перехватить исключение в клиенте, сделать частичную обработку, и кинуть опять, на этот раз специфическое для клиента исключение.

Да, на границе абстрактных слоев (например, в реализации внешнего интерфейса компоненты) желательно преобразовывать исключения. Как, впрочем, происходит и с кодами возврата - E_COMM_FAILURE, пойманный внутри ActiveX, наружу выйдет уже как какой-нибудь DISP_E_EXCEPTION с установленным для потока SetErrorInfo. Исключения не освобождают от решения этой проблемы, но хотя бы искореняют зоопарк в гомогенной языковой среде. Особенно с этим хорошо в Java и .NET.

 Профиль  
                  
 
 
Сообщение10.02.2006, 19:58 
Заслуженный участник
Аватара пользователя


17/10/05
3709
tolstopuz писал(а):
Насколько я помню, с того, что человек терпеть не может важную часть языка, на котором программирует.

Похоже, человек не одинок. EC++ появился из потребностей многих людей. Что говорит лишь об универсальности С++ -- наш пострел везде поспел -- и в ActiveX, и в MacOS, и в марсоход забрался... Разные люди используют разные аспекты языка, и можно прожить жизнь в программировании, не узнав о многих его частях.

 Профиль  
                  
 
 
Сообщение10.02.2006, 20:18 
Заслуженный участник


31/12/05
1517
незванный гость писал(а):
EC++ появился из потребностей многих людей.

Цитата:
As control passes from a throw point to a handler, destructors are invoked for all automatic objects constructed since the try block was entered. If an object has a destructor, then it must be destroyed by calling its appropriate destructor. It is difficult to estimate the total time spent on destroying automatic objects.

In general, the exception mechanism requires compiler-generated data structures and runtime support. This sometimes adds unexpectedly to the size of the program.

In embedded systems it is important for a programmer to be able to easily estimate processing time. Small code size is also important. Therefore, the two drawbacks mentioned previously cannot be ignored for embedded systems programming.

For these reasons, the technical committee decided not to include exception handling in the Embedded C++ specifications.

Да, в embedded-мире свои законы. Ни к одному из обсуждавшихся ранее примеров ни один из вышеперечисленных аргументов, к счастью, не относится, особенно к MFC. Но теперь люди, использующие для построения desktop-приложений на современных компиляторах язык C++ образца 1990 года (C с классами), могут гордо говорить, что они пишут на Embedded C++ :)
незванный гость писал(а):
Разные люди используют разные аспекты языка, и можно прожить жизнь в программировании, не узнав о многих его частях.

Страуструп пытался сделать язык внутренне согласованным, именно поэтому при однобоком взгляде и вылезают надуманные проблемы типа потери памяти при исключениях в конструкторе. Хотя C++ - язык мультипарадигмальный, каждая из его парадигм не ограничивается одной изолированной возможностью, а требует согласованных действий.

 Профиль  
                  
 
 
Сообщение10.02.2006, 20:48 
Заслуженный участник
Аватара пользователя


17/10/05
3709
:evil:
tolstopuz писал(а):
Ни к одному из обсуждавшихся ранее примеров ни один из вышеперечисленных аргументов, к счастью, не относится, особенно к MFC.

Примеры, они и есть примеры. Делаются на понятном для всех участников обсуждения языке. По моим наблюдениям, Sanyok работает со встроенными системами. Так что мне его интерес понятен. И пример всегда ограничен -- это лишь попытка объяснить проблему, а не постановка задачи.


tolstopuz писал(а):
незванный гость писал(а):
Разные люди используют разные аспекты языка, и можно прожить жизнь в программировании, не узнав о многих его частях.

Страуструп пытался сделать язык внутренне согласованным, именно поэтому при однобоком взгляде и вылезают надуманные проблемы типа потери памяти при исключениях в конструкторе. Хотя C++ - язык мультипарадигмальный, каждая из его парадигм не ограничивается одной изолированной возможностью, а требует согласованных действий.

Боюсь, с моей точки зрения, и если это действительно так -- это большой недостаток языка. Я, в общем, и так не очень высокого мнения о нем. Устарел, и безнадежно устарел. auto_ptr и STL -- это костыли для безного -- передвигаться может, но все одно -- калека. Если нормальное использование языка требует знания его в полном объеме, да еще и с полной библиотекой, то при объеме стандарта С++ -- это атас. Я предпочитаю языки, в которых можно пользоваться тем, что нужно, а про остальное забыть...

 Профиль  
                  
 
 
Сообщение10.02.2006, 21:02 
Заслуженный участник


31/12/05
1517
незванный гость писал(а):
По моим наблюдениям, Sanyok работает со встроенными системами.

Ужас. Компилятор для встроенной системы, в библиотеке которого new по умолчанию кидает исключение, лучше сразу выкинуть, а не пытаться затачивать. Хотя new(nothrow) решает проблему и при этом соответствует стандарту. А если хочется по умолчанию, то PAV уже говорил про _set_new_handler в VC++. В Борланде (судя по привычке именования классов, возможно, Sanyok работает со встроенными системами именно на BC++ Builder :)) тоже должно быть что-то похожее.
незванный гость писал(а):
Если нормальное использование языка требует знания его в полном объеме, да еще и с полной библиотекой, то при объеме стандарта С++ -- это атас. Я предпочитаю языки, в которых можно пользоваться тем, что нужно, а про остальное забыть...

Я в последнее время все чаще подумываю о Python, так как на .NET 2.0 под Linux работать не судьба. И там и там вещи, которые создатели boost вымучивают в мегабайтных заголовках, делаются легко и приятно.

 Профиль  
                  
 
 
Сообщение10.02.2006, 21:05 
Заслуженный участник
Аватара пользователя


17/10/05
3709
:evil:
Python rulez! (когда проект позволяет его использовать). Там многие вещи делаются легко и приятно. У него свои "бородавки", но их гораздо меньше, чем C++. Переходите по возможности, не пожалеете. Будете тяжело вздыхать, когда будете возвращаться на C.

 Профиль  
                  
 
 
Сообщение10.02.2006, 23:23 
Заслуженный участник
Аватара пользователя


12/10/05
478
Казань
Ладно уж, выскажусь, раз меня обсуждать стали. :) Да, работаю иногда с контроллерами, но пока только на Сях (без плюсов :) ). И, как правильно угадал Tolstopus :) , частенько использую Borland C++ Builder. Респект, Незванный гость за слова в мою защиту, но что касается моего вопроса - да, я просто не не люблю исключения и try/catch (а раз не люблю - то не использую, а раз не использую - то и не знаю, тут Tolstopus опять в точку попал :) ) . И ломаю голову, как без этого обходится. Ведь на мой взгляд, эта штука нужна только в том случае, когда кердык наступает при создании стекового объекта. Тут - никуда не денешься, как отследить такую ситуацию без исключений - непонятно... (пока что). Насчет std::auto_ptr... Век живи - век учись, но все равно - все в башке не уместишь, сам язык и без того сложный, а что бы еще и библиотеку шаблонов в мозгах держать... По-моему - проще застрелится :)

Что касается обработки ошибок, то тут вообще куча способов (гораздо более простых и понятных). По сути дела, можно просто-напросто вместо генерации исключения присваивать код ошибки переменной errno - и никакого спагетти, результат практически тот же (объект исключения - это ведь тоже по сути - нечто вроде глобальной переменной, которая затем проверяется в блоках catch. Чем блок catch красивше блока if? :) ).
И при этом никакого автоматического разматывания стека, если в этом нет необходимости.

 Профиль  
                  
 
 
Сообщение10.02.2006, 23:37 
Заслуженный участник
Аватара пользователя


17/10/05
3709
Sanyok писал(а):
Что касается обработки ошибок, то тут вообще куча способов (гораздо более простых и понятных). По сути дела, можно просто-напросто вместо генерации исключения присваивать код ошибки переменной errno - и никакого спагетти, результат практически тот же (объект исключения - это ведь тоже по сути - нечто вроде глобальной переменной, которая затем проверяется в блоках catch. Чем блок catch красивше блока if? :) ).
И при этом никакого автоматического разматывания стека, если в этом нет необходимости.

Не так все, однако, просто. Исключения не от хорошей жизни придумали, как и и их семантику паршивую. И errno тут не отделаешься.

По сути своей, exception суть структурнуй переход (в неизвестный внешний уровень). Но вот то, что он отслеживает области жизни, весьма важно. Если ловить локально, то if и try -- все едино. Но обработку можно отложить на несколько уровней, если это допускается постановкой задачи.

Интересно, что семантика исключений настолько важна, что ее начали включать в себя операционные системы. И, из-за конфликтов с RTL, весьма проблематичным образом. Но -- включают. Я не говорю про убогий виндузе, но, например Enea OSE вобще не возвращает ошибок. Если что-то не так -- системное исключение. (и API у них -- сишный).

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 39 ]  На страницу Пред.  1, 2, 3  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group