On 27.02.2013 21:46, alex_public wrote:
> Хыхы, при таком определение ошибки я тоже готов написать что все ошибки > надо обрабатывать только с помощью исключений.
А не надо искать кошку там, где ее нет.
Если у вас в требованиях есть обработка неких ситуаций, то причем тут
исключения, если нет, то вывались корректно и все, сообщив о причине —
здесь исключения самое то.
Posted via RSDN NNTP Server 2.1 beta
Re[46]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
Здравствуйте, Vzhyk, Вы писали:
V>Неа. Код ты пишешь в первую очередь для людей, тех кто его потом читать V>будет, поддерживать (в том числе и для себя), компилятору же пофиг, V>абсолютно.
Ну так поинт состоит в том, что коды возрата ПОНЯТНЕЕ, потому, что они ЛОКАЛЬНЕЕ.
Не надо смотреть в 100500 мест, где что могло случиться или не случиться, где могли чего-то обеспечить или не смогли, ну есть у тебя пять вызвавших друг друга функций. Просто читаешь их код и всё. Ошибка содержится ровно в этих 100 строках, а не "где-то ещё"...
V>Дальше, если в твоем коде так называемая "ошибка" представляет собой V>типичное поведение программы, то нафига исключение, а то таким макаром и V>if a<b можно через исключение написать.
Да, это очень хороший и правильный тезис и я его абсолютно разделяю. Дальше у нас возникает такая беда, что в нижележащей функции мы не знаем, это штатная ситуация или таки ошибка, которая уже достойна исключений. поэтому по умолчанию, ну это если у нас принято писать переиспользуемый код, а не велосипед на каждый случай, нам логичнее почти всё возвращать через коды, вернее ещё лучше не через коды, а так разрабатывать интерфейсы своих классов и функций, что бы у них просто было какое-то логичное поведение, включающее и штатные варианты провала. Это идеал, если идеал труднодостижим, то мы, значит, делаем коды возврата, и только для каких-то совсем ужасных раскладов делаем исключения.
А на вызывающей стороне, там где мы уже знаем, ошибка это или штатная ситуация, мы обычно уже можем эту ошибку обработать, по крайней мере начать обрабатывать...
и тогда возникает вопрос, а зачем нам тут уже исключения, если мы и так можем начать обрабатывать?..
на самом деле моя проблема мне стала после этой дискуссии понятна лучше.
Я понял, что в коде без исключений есть некоторая мат. модель кода, которая позволяет мне с ним работать достаточно продуктивно и хорошо. Писать assert's, проверять пред и пост условия, инварианты циклов и т. д.
Это таки то, что описано у Дейкстры в "Дисциплине программирования" и у его последователей.
Традиционно такой подход к организации императивного кода получил название "процедурное программирование".
Для функциональщины тоже есть подходящий мат. аппарат. А вот для "кода с исключениями" я такого аппарата не знаю.
Может его кто-то таки придумал, просто я не в курсе? Это легко может такое быть. И тогда бы, если бы такой аппарат был, многие вопросы, где там стоит или не стоит пихать исключения, скорее всего можно было бы формально задать и получить на них формальный ответ, а так рассусол и кустарзина с вкусовщиной сплошные выходят...
Слушайте, люди добрые, а правда, есть мат аппарат для анализа кода с иключениями?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Patalog, Вы писали:
P>Ничем не отличается от исключений, кроме то, что в случае исключений мы можем на это забить, так как уровнем выше мы словим исключение по базе, а в твоем случае мы вынуждены пробрасывать\переформатировать, иначе потеряем ошибку и останемся в невалидном состоянии.
Дык то, что при рефакторинге мы можем на чать оного забить и понадеяться, что оно само как-нибудь -- это скорее минус, чем плюс жеж?
так как если оно само не сможет даже всего раз из 10, то в те места прийдётся вникать ДВАЖДЫ...
И хорошо, если оба раза ДО релиза...
P>На мой вкус — кода заметно меньше, код прозрачнее, по happy path уж точно, что не маловажно для чтения оного через N времени. P>А то иногда бывает так, что за обработкой ошибок не видно основной логики.
Ну так тоже не надо писать. На исключениях говнокод породить ещё проще, чем на кодах возврата... И при том и при другом подходе есть удачные и не особо удачные реализации. А самые удачные обычно совмещают ОБА подхода. Что-то через исключения, а что-то через коды...
P>ЗЫ В библиотеках я по возможности предоставляю два вида интерфейса — с исключениями и с кодом ошибки, как это сделано в boost.asio
Ну для библиотек это часто хороший выбор. +100500
Особенно, если не понятно каких тактик обработки ошибок придерживаются пользователи.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Vzhyk, Вы писали:
>> То есть "ошибка" -- это то, после чего программу надо аварийно >> отгружать? Я верно понял или нет? V>В общем-то так. Все остальное — не ошибка, а требование.
Дык если ты тоже придерживаешься позиции, что исключения надо кидать только тогда, когда случилось что-то такое, что программу налдо отгрузить, то у нас с тобой очень схожие позиции по этому вопросу.
Только я считаю, что раз мы всё равно аварийно отгружаемся, то нам ещё и валидность нафиг не упёрлась и утечки не критичны. Достаточно того, что бы то, что не утекло смогло разрушиться без фейерверков...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[47]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
On 27.02.2013 22:02, Erop wrote:
> Ну так поинт состоит в том, что коды возрата ПОНЯТНЕЕ, потому, что они > ЛОКАЛЬНЕЕ.
А код легче читать не потому, что он локальнее, а потому, что он
лаконичнее. Впрочем, как и книги. Пример Лев Толстой, которого читать
вообще практически невозможно, зато все его отступления локальны.
Правило простое, если можно что-то не писать — не пиши.
Второе, код функции больше страницы человеком вопринимается очень плохо,
а проверки кодов возврата его раздуют так или иначе. Если ты навернешь
на дэфайнах, код станет еще сложнее читать, ибо хер знаешь, во что там
твои дэфайны развернуться (но иногда это нормально выглядит).
> Да, это очень хороший и правильный тезис и я его абсолютно разделяю. > Дальше у нас возникает такая беда, что в нижележащей функции мы не > знаем, это штатная ситуация или таки ошибка, которая уже достойна > исключений.
Знаем, потому как есть требования. Если их нет, их надо сформировать.
> А на вызывающей стороне, там где мы уже знаем, ошибка это или штатная > ситуация, мы обычно уже можем эту ошибку обработать, по крайней мере > начать обрабатывать... > и тогда возникает вопрос, а зачем нам тут уже исключения, если мы и так > можем начать обрабатывать?..
И так мы зацикливаемся. А это нам надо? Нет.
> Традиционно такой подход к организации императивного кода получил > название "процедурное программирование". > Для функциональщины тоже есть подходящий мат. аппарат. А вот для "кода с > исключениями" я такого аппарата не знаю.
Я бы так не утверждал. Но если его нет и он нужен, придумают те, кто
занимается теорией программирования. Мы здесь все больше практики и
теорией программирования не занимаемся (если тебе это интерсно, то
понятно ответ надо искать не на этом форуме).
Исключения удобны и выгодны. Неужели отсутсвие математической модели в
данный момент должно нам запрещать использовать некое явление?
> Может его кто-то таки придумал, просто я не в курсе? Это легко может > такое быть. И тогда бы, если бы такой аппарат был, многие вопросы, где > там стоит или не стоит пихать исключения, скорее всего можно было бы > формально задать и получить на них формальный ответ, а так рассусол и > кустарзина с вкусовщиной сплошные выходят...
Ну что тебе сказать. Поднимаешь несколько десятков статей по теории
программирования, ищешь ответ, а потом нам здесь рассказываешь.
On 27.02.2013 22:08, Erop wrote:
> Только я считаю, что раз мы всё равно аварийно отгружаемся, то нам ещё и > валидность нафиг не упёрлась и утечки не критичны. Достаточно того, что > бы то, что не утекло смогло разрушиться без фейерверков...
Конечно.
Я не понимаю, зачем вы здесь, хором надували муху до размеров слона.
У нас есть всегда некие требования к любому модулю (части) программы и
мы именно их и должны удовлетворить (ну или расширить требования по мере
разработки). Все что выходит за требования — корректно умираем.
Но не забываем о том, что программу мы пишем для людей и посему должны
быть маскимально лаконичны и понятны читателю.
И еще момент, не забываем, что исключения происходят в редких ситуациях,
а коды возврата нужно проверять, а это может плохо сказаться на скорости
работы программы.
Posted via RSDN NNTP Server 2.1 beta
Re[48]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
Здравствуйте, Vzhyk, Вы писали:
>> Для функциональщины тоже есть подходящий мат. аппарат. А вот для "кода с >> исключениями" я такого аппарата не знаю. V>Я бы так не утверждал. Но если его нет и он нужен, придумают те, кто V>занимается теорией программирования. Мы здесь все больше практики и V>теорией программирования не занимаемся (если тебе это интерсно, то V>понятно ответ надо искать не на этом форуме).
В смысле "не утверждал"? Ты думаешь, что я таки знаю, но скрываю?
Его вроде как и правда нет. Потому-то код с частыми исключениями так похож на goto-спагети...
Я вполне допускаю, что когда такую мат. модель построят, всё станет сильно лучше и понятнее. Пока что понятно только одно -- базовая и строгая гарантии такую можель построить не позволяют. Увы.
V>Исключения удобны и выгодны. Неужели отсутсвие математической модели в V>данный момент должно нам запрещать использовать некое явление?
А что значит "выгодны"? В чём выгода измеряется? отсутсвие модели мешает выработать оптимальную стратегию использования, например...
V>Ну что тебе сказать. Поднимаешь несколько десятков статей по теории V>программирования, ищешь ответ, а потом нам здесь рассказываешь.
Я как-то искал и не нашёл...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[49]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
On 27.02.2013 22:29, Erop wrote:
> В смысле "не утверждал"? Ты думаешь, что я таки знаю, но скрываю?
Нет. Если ты не знаешь, то это не говорит, что его нет.
> Пока что понятно только одно -- базовая и > строгая гарантии такую можель построить не позволяют. Увы.
Утверждения пошли, а можно ссылочки на твои публикации по теории
программирования с обоснованием отсутсвия оной модели или ее невозможности.
> А что значит "выгодны"? В чём выгода измеряется? отсутсвие модели мешает > выработать оптимальную стратегию использования, например...
Если тебе нужна оптимальная стратегия, то садишьс яи разрабатываешь
модель. В любом случае, если явление есть, то и модель строится.
Моя же выгода чисто утилитарная — время написания программы и
соответсвенно стоимость.
> Я как-то искал и не нашёл...
Ну я тебе еще могу подкинуть темку по которой ты будешь искать и многого
не найдешь, не будучи докой в этой теме. Сейчас практически в любой
научной дисциплине сначала нужно достигнуть некоторого уровня знаний,
чтобы найти что-то посерьезнее научно-популярных изложений.
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, jazzer, Вы писали:
J>>Код "прямой и модульной изначальной архитектуры" на кодах возврата на в студию. С обоснованием прямизны и модульности. J>>И не забывай, мы тут говорим об обработке ошибок, так что потрудись убедить нас, что ни одной ошибки случайно не пропущено и что обрабатывать ошибки кодами возврата на порядок удобнее и безопаснее, чем исключениями. J>>Просим! Просим!
_>Я нигде не говорил, что обрабатывать ошибки кодами возврата на порядок удобнее и безопаснее, чем исключениями. Надо читать собеседников внимательнее.
Супер. Так если кодами ошибок не удобнее и не безопаснее, зачем обрабатывать ошибки ими?
И что там насчет "прямой и модульной изначальной архитектуры" на кодах возврата? Или у тебя, кроме необоснованных заявлений, ничего нет?
_>Мой тезис был в том, что в большинстве практических случаев (однако естественно что ситуации оптимальные для исключений всё же есть) замена кодов возврата на исключения не приносит вообще никакой пользы.
Главное отличие исключений от кодов возврата в том, что коды возврата по умолчанию игнорируются, а исключения — наоборот.
Т.е. чтоб проигнорировать исключение, нужно написать специальный и очевидный любому читающему код.
А чтобы проигнорировать код возврата, достаточно просто забыть его обработать.
В этом главный рулез исключений — при ошибке выполнение гарантировано не пойдет дальше, если только не принято специальных мер явно.
А с кодами возврата — ошибка будет гарантировано проигнорирована и исполнение пойдет дальше, радуя пользователя фейерверками.
_>Вреда правда тоже особого нет, разве что небольшое увеличение объёма кода.
Небольшое — это в два раза за счет "if(err)return err;" после каждой строчки
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, jazzer, Вы писали:
J>>Зачем рушить? Ведь есть же такой уровень, при котором программа может принять осмысленное решение, что делать в случае отсутствия файла? E>Чтобы можно было позволить себе не рушить, надо обеспечивать высокий уровень гарантий безопасности при исключениях, а это и есть то, что удорожает использование исключений...
А этот уровень разве не нужен при использовании кодов возврата?
J>>Тут я согласен, если под "расползается" ты имеешь в виду, что весь код должен быть устойчив к исключениям. E>Да, точно так.
J>>И если в случае кодов ошибок это расползание видно явно и, как следствие №1, замусоривает код до невозможности, а как следствие №2, поощряет ленивых программеров забивать на обработку кодов, то в случае исключений код становится чистым и ясным, а игнорирование ошибки невозможно.
E>IMHO, всё ровно наоборот. E>1) Подумали ли о том, что будет, если провалится то или это мето или просто так взяли и написали "чисто и ясно" и расслабились, НЕ ВИДНО.
Аналогично не видно, обработали ли код возврата или это просто функция возвращает void, или если обработали, то все ли возможные значения обработаны. E>2) Провал чего-то может быть очень сложным, рекурсивным и вообще маорпонимабельным.
И что? Он будет точно таким же и с кодами возврата. И действия по восстановлению работоспособности программы будут точно такими же. E>3) Поведение описано в программе неявно, неверефицируемо, нетестируемо и труднопонимаемо...
Как в таком случае насчет RAII и деструкторов? Они тоже зовутся в программе неявно
Насчет нетестируемости — так трудно вызвать исключение?
Насчет труднопонимаемости — вообще не аргумент, имхо. Мне вот гораздо труднее установить корректность кода на кодах возврата.
J>>Ага. В каждой строчке (или еще хуже — в каждом подвыражении, которое теперь приходится разбивать на expression statement-ы и обвешивать замечательными "if(err)return err;"). Офигительная разница. E>Зачем это делать в каждом подвыражении?..
Потому что каждое подвыражение может обломаться. С исключениями мы можем об этом не беспокоиться, а с кодами возврата придется выражения разбить на подвыражения и проверять код возврата каждого.
J>>Разве? Чем документирование кодов возврата отличается от документирования исключений? E>Тем, что исключение для объемлющего кода выглядит как goto. поток управления в ВЫЗВАЮЩЕМ коде становится непроцедурным...
как return, а не как goto. Разницу видишь?
J>>Не могу согласиться, сорри. return в середине функции эквивалентен goto на конец функции. Ты у нас сторонник подхода "Из функции должен быть ровно один return"? Если нет, то объясни мне, чем отличается исключение от множественного return. E>Читай Дейкстру. E>Я не противник goto, кстати, и не противник множественного return E>Я противник кода, который можно интерпретировать, как набор операций последовательно переводящих программу из одного состояния в другое. E>То есть, если процедурность не страдает, то в goto нет проблемы (например выход из вложенного цикла по goto не проблема), а если страдает, то всё плохо и без goto
Замечательно. А теперь вспомним, что исключение — это по сути return, против которого ты ничего не имеешь.
J>>Ты, наверное, на ФУПМе учился E>Нет, на проблемах. Но какое это имеет отношение к теме?
Ну фупмов теорией грузят в большом количестве.
J>>Можешь закидать меня радиоактивными какашками, но я с этой идиомой не знаком. E>Крайне настоятельно тогда рекоммендую... E>Там с азов всё идёт, так что можешь знакомые главы тупо пролистывать, но книжка очень дельная, и программисту её,в ернее изложенные в неё идеи, знать стоит. Есть по-русски и по-японски, ну и английский вариант тоже есть, есен пень
спасибо, будет время — почитаю
J>>Сейчас прочитал в вики по диагонали и пришел к выводу, что эта радость не предусматривает return в середине функции — я прав? E>В математически чистом варианте да, вернее для каждого return надо будет отдельно доказать попадание в постусловие. На практике бывает много кода, который очевидно не трудно доказуем таким образом. Даже если return'ов много...
Ну так код на исключениях элементарно переписывается на таковой на return'ах
J>>Во-вторых, просто из определения, если я его правильно понял, weakest precondition — это условия, при которых операция даст нужный результат. E>Это слабейшее предусловие заданного постусловия.
ОК, минимальные условия, при которых операция даст нужный результат.
J>>Так вот, weakest precondition для fopen с ненулевым результатом будет точно таким же, как для fopen, бросающей исключения в случае неудачи. J>>Поправь, если не так. E>Да так. Дальше у нас возникает вопрос, допускает ли предусловие программы неоткрывающиеся файлы. Если таки да, то вариант с исключениями не канает, потому, что в некоторых допустимых предусловиями состояниях в результате выполнения попадём в состояние где выполненность постусловия неопределена...
Сорри, а почему тут предусловие программы (т.е. одно на всю программу), а не конкретного вызова? Очевидно, одни файлы критичны, а на другие можно и забить
Так что у каждого вызова fopen свое постусловие, и соответственно свое соответствующее предусловие.
Здравствуйте, Erop, Вы писали:
E>на самом деле моя проблема мне стала после этой дискуссии понятна лучше. E>Я понял, что в коде без исключений есть некоторая мат. модель кода, которая позволяет мне с ним работать достаточно продуктивно и хорошо. Писать assert's, проверять пред и пост условия, инварианты циклов и т. д. E>Это таки то, что описано у Дейкстры в "Дисциплине программирования" и у его последователей. E>Традиционно такой подход к организации императивного кода получил название "процедурное программирование". E>Для функциональщины тоже есть подходящий мат. аппарат. А вот для "кода с исключениями" я такого аппарата не знаю. E>Может его кто-то таки придумал, просто я не в курсе? Это легко может такое быть. И тогда бы, если бы такой аппарат был, многие вопросы, где там стоит или не стоит пихать исключения, скорее всего можно было бы формально задать и получить на них формальный ответ, а так рассусол и кустарзина с вкусовщиной сплошные выходят...
E>Слушайте, люди добрые, а правда, есть мат аппарат для анализа кода с иключениями?
Мой формальный ответ такой: код на исключениях элементарно переписывается один-в-один на код с кодами возврата и return'ами, для которого все давно доказано (то, что множественные return'ы переписываются в гроздь if'ов, надеюсь, специально доказывать не надо?)
Концептуально исключения — это просто сахар для кодов возврата (а errno будет еще более близкой аналогией).
Здравствуйте, Vzhyk, Вы писали:
V>А не надо искать кошку там, где ее нет.
V>Если у вас в требованиях есть обработка неких ситуаций, то причем тут V>исключения, если нет, то вывались корректно и все, сообщив о причине — V>здесь исключения самое то.
Фокус в том, что если вы внимательно почитаете эту темку, то увидите что довольно много народа придерживается совсем другой позиции. А именно, что исключения надо использовать гораздо шире, чем описали вы. Вот с ними лично я тут и спорю понемногу. )))
Здравствуйте, jazzer, Вы писали:
J>Супер. Так если кодами ошибок не удобнее и не безопаснее, зачем обрабатывать ошибки ими?
Я же писал уже, что замена кодов ошибок на исключения обычно приводит к небольшому увеличению объёма работы, при этом не давая вообще никаких бонусов от этого увеличения.
J>И что там насчет "прямой и модульной изначальной архитектуры" на кодах возврата? Или у тебя, кроме необоснованных заявлений, ничего нет?
Про архитектуру речь шла не в связи с кодами возврата/исключениями, а по поводу функции, которая вроде как может вызывать внутри себя другие с вложением друг в друга десятками и при этом там нормально обрабатывать ошибки в самого нижнего уровня на самом высшем. В большинстве случаев это как раз пример немодульного говнокода. По нормальному каждый уровень кода должен полностью отвечать за свою функциональность, скрывая все детали внутри себя. Инкапсуляцию и другие методы придумали же не просто так.
J>Главное отличие исключений от кодов возврата в том, что коды возврата по умолчанию игнорируются, а исключения — наоборот. J>Т.е. чтоб проигнорировать исключение, нужно написать специальный и очевидный любому читающему код. J>А чтобы проигнорировать код возврата, достаточно просто забыть его обработать. J>В этом главный рулез исключений — при ошибке выполнение гарантировано не пойдет дальше, если только не принято специальных мер явно. J>А с кодами возврата — ошибка будет гарантировано проигнорирована и исполнение пойдет дальше, радуя пользователя фейерверками.
Это здесь уже обсуждали. И этот тезис действует только в одном очень вырожденном случае. Это если какие-то функции будет писать нормальный специалист, а клиентских код для них будет писать говнокодер. Тогда теоретически исключения могут оказать некий воспитательный эффект. Но это слишком вырожденный случай, что бы принимать его за аргумент. К примеру у нас (мы не используем дешёвых криворуких кодеров) он вообще не имеет смысла.
_>>Вреда правда тоже особого нет, разве что небольшое увеличение объёма кода. J>Небольшое — это в два раза за счет "if(err)return err;" после каждой строчки
Вообще то речь шла о том, что исключения дают небольшое увеличение объёма кода...
E>Будущее мобильной разработки, Tizen 2.0. По моему, шикарно... 6 new, 3 каста, 1 delete и даже E_SUCCESS
Помнится, я в одном из форумов объяснял epic fail Symbian'а и тотальный уход в пользу iOS/Android именно подобным кодом и подходом к программированию вообще. Некоторые были не согласны, и превозносили Symbian как прекрасную ОС, якобы предательски убитую г-ном Элопом (и уже под это дело вагон теорий заговора).
Теперь о том, откуда ноги растут у этого безобразия. "Вы не поверите" (С), но — из Intel. А туда, в свою очередь, попало после "перекрёстного опыления" Intel'овского поделия Moblin кодом из Maemo (кстати, в результате тяжелых родов получилось Meego, опять же, ожидаемо провалившаяся в силу тех же причин — "удобства" разработчиков портировать софт на этот вариант линукса).
А потом все было щедро сдобрено корейским подходом, ведь изначально Tizen — это проект LiMo. По сути, аналог Android, даже в одно время "зачинались", просто LiMo гуглу продаться никак не могли. Собственно, когда Intel инвестировал в LiMo, и случилось переименование в Tizen.
Так вот, наслоения древнего кода на еще более древний, притом, само собой, без надлежащего тестирования, делают практически неосуществимой возможность безопасного применения современных технических средств, в том числе исключений.
Взлететь оно, конечно, не взлетит — как и любая другая ОС, столь недружественно относящаяся к разработчику. Посему никакой речи о "будущем мобильной разработки" не ведется.
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, jazzer, Вы писали:
J>>Супер. Так если кодами ошибок не удобнее и не безопаснее, зачем обрабатывать ошибки ими?
_>Я же писал уже, что замена кодов ошибок на исключения обычно приводит к небольшому увеличению объёма работы, при этом не давая вообще никаких бонусов от этого увеличения.
Можно твое так называемое "небольшое" озвучить в цифрах?
J>>И что там насчет "прямой и модульной изначальной архитектуры" на кодах возврата? Или у тебя, кроме необоснованных заявлений, ничего нет?
_>Про архитектуру речь шла не в связи с кодами возврата/исключениями, а по поводу функции, которая вроде как может вызывать внутри себя другие с вложением друг в друга десятками и при этом там нормально обрабатывать ошибки в самого нижнего уровня на самом высшем. В большинстве случаев это как раз пример немодульного говнокода. По нормальному каждый уровень кода должен полностью отвечать за свою функциональность, скрывая все детали внутри себя. Инкапсуляцию и другие методы придумали же не просто так.
Show me the code.
Пусть будет вот такой стек вызовов: read_profile -> load_files -> load_file -> read_file -> read_header -> read_field_group -> read_named_field -> read_integer.
И у тебя вместо циферки встретилась буковка.
Теперь расскажи нам про уровни и инкапсуляцию и прямую архитектуру и как тут будут рулить коды возврата.
И имей в виду, что read_field_group зовет 50 разных read_named_field, read_header — 20 разных read_field_group, а load_files — 10 load_file.
И заодно еще расскажи, как ты гарантируешь, что твой read_profile не вернет true в случае ошибки где-то в потрохах загрузки.
Без этого дальнейший разговор не будет иметь никакого смысла.
J>>Главное отличие исключений от кодов возврата в том, что коды возврата по умолчанию игнорируются, а исключения — наоборот. J>>Т.е. чтоб проигнорировать исключение, нужно написать специальный и очевидный любому читающему код. J>>А чтобы проигнорировать код возврата, достаточно просто забыть его обработать. J>>В этом главный рулез исключений — при ошибке выполнение гарантировано не пойдет дальше, если только не принято специальных мер явно. J>>А с кодами возврата — ошибка будет гарантировано проигнорирована и исполнение пойдет дальше, радуя пользователя фейерверками.
_>Это здесь уже обсуждали. И этот тезис действует только в одном очень вырожденном случае. Это если какие-то функции будет писать нормальный специалист, а клиентских код для них будет писать говнокодер.
О да, это достойный аргумент
_>>>Вреда правда тоже особого нет, разве что небольшое увеличение объёма кода. J>>Небольшое — это в два раза за счет "if(err)return err;" после каждой строчки _>Вообще то речь шла о том, что исключения дают небольшое увеличение объёма кода...
По сравнению с чем? С ручным пробрасыванием кодов возврата? И у тебя, конечно же, есть результаты измерений?
Плюс ты, наверное, говоришь только про объем бинарника, так как с полотенцами проверок кодов возврата в исходниках и так все понятно, правда?
хъ
_>Фокус в том, что если вы внимательно почитаете эту темку, то увидите что довольно много народа придерживается совсем другой позиции. А именно, что исключения надо использовать гораздо шире, чем описали вы. Вот с ними лично я тут и спорю понемногу. )))
Нет здесь никакого противоречия.
Код, которой кидает исключение\код возврата обычно не может предположить насколько фатально эта ошибка для программы в целом.
Как вы это определите в нек. библиотеке, например? Такое возможно только в plain коде типа хелло ворлда, где все просматирвается насквозь.
Если в требованиях к методу есть обработка фейла открытия пресловутого файла — он ее обработает, не важно через if или try.
Если нет — сам кинет исключение.
хъ
P>>Ничем не отличается от исключений, кроме то, что в случае исключений мы можем на это забить, так как уровнем выше мы словим исключение по базе, а в твоем случае мы вынуждены пробрасывать\переформатировать, иначе потеряем ошибку и останемся в невалидном состоянии.
_>Такие дела обычно приводят к нарушению инкапсуляции и т.п.. По нормальному каждый уровень кода должен оставлять все внутренние детали внутри себя.
Это в любом случае лучше чем забы(и)ть про обработку кодов возврата.
Кроме того, подход с сильно типизированными исключениями я не пробовал в боевом применении, дальше экспериментов дело не пошло.
В то же время, мне сильно нравиться подход товарища zaufi, но пока все не сподоблюсь попробовать.
У меня (к примеру) parse_error с указанием места фейла в потоке бит никому ничего не должен, он общий для неск. уровней иерархии вазовов.
Возможно это нарушение инкапсуляции, но искусство ради искусства считаю не практичным.
ЗЫ Про то как именно ты нормально оставляешь все детали кодов возврата внутри себя ты опять скромно умолчал. =)
Здравствуйте, SkyDance, Вы писали:
SD>Теперь о том, откуда ноги растут у этого безобразия. "Вы не поверите" (С), но — из Intel. А туда, в свою очередь, попало после "перекрёстного опыления" Intel'овского поделия Moblin кодом из Maemo (кстати, в результате тяжелых родов получилось Meego, опять же, ожидаемо провалившаяся в силу тех же причин — "удобства" разработчиков портировать софт на этот вариант линукса).
MeeGo — это как раз сплав из Moblin/Maemo (редхат подобная система c Zypper/RPM) — при чём то что на телефонах Nokia N9/N950 — то только Maemo 6 с изменённым названием на Meego Harmattan (Debian based dpkg/deb система).
Разработка довольно простая, портирование тоже (Qt/QML/OpenGL/Clutter и тд.)
И провалилось оно по политическим а не техническим причинам — не нужно было Микрософту конкурента в дополнение к Андроиду и иОС — соответственно НР слило WebOS викупив Палм а Nokia Maemo/MeeGo продавшись Микрософту.
В Тизен основа Linaro с EFL/E17 вместо Qt.
EFL сишная библиотека, соответственно обёртки над ней используют возврат кода ошибки, по моему логично.
SD>Взлететь оно, конечно, не взлетит — как и любая другая ОС, столь недружественно относящаяся к разработчику. Посему никакой речи о "будущем мобильной разработки" не ведется.
Добавляйте IMHO.Время покажет — у Самсунга ресурсы есть — сегмент Бады заменит точно.
использовал Blackberry 7130 — Nokia 5800 — Palm pre+ — HTC Desire — Nokia N9 до сейчас.
могу сравнивать.
Здравствуйте, jazzer, Вы писали:
J>А этот уровень разве не нужен при использовании кодов возврата?
Нет. В случае отсутсвия исключений нужно обеспечить совсем другое соблдения по выходу из любой функции её постусловий. Это локальное требование, которое проще тестировать, например при модульном тестировании, проще обеспечивать, проще проверять статически и которое ВСЁ РАВНО надо обеспечивать...
J>Аналогично не видно, обработали ли код возврата или это просто функция возвращает void, или если обработали, то все ли возможные значения обработаны.
Этот элементарно делается статическим анализатором кода при комите, например...
J>И что? Он будет точно таким же и с кодами возврата. И действия по восстановлению работоспособности программы будут точно такими же.
Нет, не точно такими же. В случае исключений нам надо написать некий универсальный всемогутер, написанию которого, кроме всего прочего, ещё и сам язык С++ протвится, вернее его нереинтерабельная модель исключений.
А в случае кода без исключений мы обычно имеем вполне перечислимый набор сценариев, которые надо обработать, и КОТОРЫЕ НАДО ПРОВЕРИТЬ.
J>Как в таком случае насчет RAII и деструкторов? Они тоже зовутся в программе неявно
Обычно RAII в программе зовётся явно таки... Неявно только деструктор и в деструкторах многое пожтому делать нельзя...
J>Насчет нетестируемости — так трудно вызвать исключение?
Всех типов во всех местах? Наверное нетрудно, если как-то автоматизировать это дело, только долго. И не понятно щачем. Кроме того, я не слышал, чт бы кто-то проводио такие тесты и не встречал подходящего для их провеения инструментария...
А ты слышал? Вот в программах, в разработке которых ты принмал уастие наверняка декларировалась как минимум слабая гарантия. Так? Как проверялось, что она реально обеспечена, а не только задекларирована?..
Мне такие прецеденты не известны. За исключением нескольких успешных попток переноса кода, при котором вылазили ошики, ясный пенью. И ВО ВСЕХ известных мне подробно случах переноса больших продуктов, выяснялось что базовая гарантия во многих местах нарушена на самом деле... При этом в некоторых нарушена так, что без весьма неыормального рефакторинга не чиниится, то есть гарантия не обеспечивалась даже на уровне архитектуры...
Всё массовые коробочные или серверные продукты...
Но, подожим, это я неперщик такой. Расскажи как оно бывает лучше, если знаешь о таких примерах
J>Насчет труднопонимаемости — вообще не аргумент, имхо. Мне вот гораздо труднее установить корректность кода на кодах возврата.
Да нет никаких особенностей у кодов возврата по сравнению с "просто функциями".
Единственная особенность -- результаты некоторых типов нельзя просто терять. То есть некоторые функции нельзя вызвать как процедуры. Очень жаль, что в С/С++ нет возможность попросить компилятор проверять это дело, кстати. Но можно статический анализатор попросить, зато, что спасает.
J>Потому что каждое подвыражение может обломаться. С исключениями мы можем об этом не беспокоиться, а с кодами возврата придется выражения разбить на подвыражения и проверять код возврата каждого.
Тут есть две беды.
1) С исключениями мы не можем об этом не беспокоиться. Мы должны беспокоиться об этом тоже, но не конкретно, а в общем. Весь разговор о том, при каких методах что проще. Обычно всемогутеры сложнее и ненадёжнее... А решения по месту в некоторых местах могут отсутствовать, но тут базовая гарантия ничем не лучше, наоборот хуже. Её наличие трунее проверить. а её требование к тому же, часто ещё и избыточно.
2) Есть куча операций, которые не могут сфейлится пока не случилось фатального какого-то фейла.
Те же рациональные числа, например. Чем деление на ноль в рац. числах так уж принципиально отличается от того же в double. Тем не менее double никаких С++ исключений не кидает и никто не жалуется вроде как...
J>как return, а не как goto. Разницу видишь?
Как long_jump, но с раскруткой стека, если быть строгими. Разницу между LJ и return видишь?..
Разница в том, что в каждом конкретном месте мы не можем понять откуда мы сюда можем попасть. Множество "откуда" открытое... И множество "куда", на самом деле тоже. А с return всё не так. Попасть мы можем вообще только из одного места, а выйти можем только в точку возвратта их функции...
просто пример, после вызова какой-о фцнкции я могу написать assert( мы выполнили постусловия );
Как мне написать такой assert для случая с исключениями, например?..
Я ещё раз повторяю, код в котором я не могу написать в каждм месте assert( если ещё не пора отгружать программу, то должно выполняться это ), является НЕПОНЯТНЫМ. В этом и состоит идея Дейкстры. Она очень мощная и продуктивная, позволяет писать много автоматических и полуавтоматических рантайм. статических и юнит-проверок. Это грандиозно удешевляет отладку, поддержку и является очень неплохой документацией, к тому же ещё и самопроверяющейся.
Массовое использование исключений заставляет нас от этого отказаться. Ради чего?
Вернее чем это предлагается заменить?..
J>Замечательно. А теперь вспомним, что исключение — это по сути return, против которого ты ничего не имеешь.
Нет, это, по сути динамически вычисляемый long jump, против которого я имею ОЧЕНЬ МНОГО!
J>Ну фупмов теорией грузят в большом количестве.
Прблемы -- факультет практиков и эксперементаторов, так что мимо
J>спасибо, будет время — почитаю
Очень советую. Безотносительно к исклчениям.
J>Ну так код на исключениях элементарно переписывается на таковой на return'ах
Нет, это не так. Смотри выше.
J>ОК, минимальные условия, при которых операция даст нужный результат.
Да, вернее это оператор, который по КУСКУ кода и его постусловию может вычислить такие предусловия. Да.
J>Сорри, а почему тут предусловие программы (т.е. одно на всю программу), а не конкретного вызова? Очевидно, одни файлы критичны, а на другие можно и забить
При том, что мы в конце концов хотим получить программу, которая делает какие-то конкретные действия. по переходу из своего предусловия в своё постусловие. Это цель разработки ПО.
Каждый конкретный вызов ни для чего. кроме как для небольшого приближения к этой цели нам не нужен...
J>Так что у каждого вызова fopen свое постусловие, и соответственно свое соответствующее предусловие.
Конечно. Но нас интересует же надёжность программы в целом, а не то, что этот вот конкретный fopen не упадёт?..
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском