Здравствуйте, Alexey Chen, Вы писали:
WH>>Знакомые все лица... AC>Вроде набрудершафт не пили.
Человек с ником hedgehog на соседнем сайте тоже пытался на исключения наезжать...
AC>Про фанатизм и религию идеальной программы я уже говорил.
Ни какого фанатизма. Один прагматизм.
AC>Не понял, что ты хотел доказать? Что хорошо написанный код, лучше плохо написанного? ИМХО, это докозательства не требует. AC>Что без RAII и исключений хороший код писать нельзя или писать его сложнее? Ну, это просто пробел в твоем образовании.
Вопрос о мем образовании рекомендую оставить в покое. Давай конкретно. Как переписать этот код без RAII чтобы он получился не мение читабельным и без лишней ручной работы. AC>Конкретно приведенный тобой пример, слабо изменится, если убрать из него исключения, заменив на goto.
Могу представить еще одну шедевриальную реализацию эой же функции на 144 строки... Там goto использован... AC>Просто ты привык использовать исключения, и считаешь, что любой другой способ есть лажа.
Все зависит от ситуации. Но для исключительных ситуаций исключения рулят. Болие того код использующий исключения для оповещения о редких ошибках работает не медленней чем на кодах возврата. AC>Исключения хороши для передачи ошибки на несколько уровней вверх, и не факт, что такая схема обработки ошибок есть верная всегда.
Привиди пример когда это не оправдано.
AC>Еще раз. Я никогда не говорил, что исключения — зло, я говорил, что они не всегда нужны, как и RAII. AC>И использовать исключения без RAII практически невозможно, но можно использовать RAII без исключений там, где оно естественно. AC>Нпример, захват COM обьекта.
ИМХО RAII естественно для любого захвата любого ресурса. Затраты на написание врапера сравними с однократным захватом/освобождением ресурса. Но если ресурс во врапере то у меня уже не болит голова ни о исключениях ни о return'ах ни о чем. К томуже что тоже не маловажно не смешивается логика работы с ресурсом с логикой работы алгоритма в котором этот ресурс использован.
AC>Лично мне монописсуально какой способ обработки ошибок использовать, я писал и так и эток, и повсякому можно сделать просто, понятно и надежно.
Веришь нет я тоже. Но после RAII к goto я возвращаться не намерен.
AC>P.S. AC>Удивительно, но люди часто забывают, что C++ — всего лишь инструмент, и решают не поставленую задачу, а задачу — решения поставленной задачи способом наиболее соответствующем тому который-используют-в-своих-книгах-крутые-мужики.
Да мне глубоко по барабану что крутые мужики используют в своих книжках. Я исхожу из чисто практических соображений.
... << RSDN@Home 1.1.3 beta 1 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, Alexey Chen, Вы писали:
WH>>>Знакомые все лица... AC>>Вроде набрудершафт не пили. WH>Человек с ником hedgehog на соседнем сайте тоже пытался на исключения наезжать...
Странно, что мои постинги рассматриваются как наезд. Или любая точка зрения несовпадающая с точкой зрения _гуру_ есть наезд?
WH>... Но после RAII к goto я возвращаться не намерен.
Интересная точка зрения. Особенно противопоставление двух несвязанных вещей. Вместе пользовать не пробывал?
Меня позабавил чей-то постинг в котором было написанно что 'вся логика в RAII' :).
Но что меня действительно удивляет на различных форумах, так это то, что приводит некто какой-то вырожденный пример и делает вывод что _поэтому_ нужно использовать _X_. Когда я говорю, что чувак не прав и _X_ отсюда никак не следует, появляется _гуру_, который пытается меня убедить, что _X_ надо использовать вообще всегда! Что-то мне подсказывает, что вещей, которые надо использовать всегда, и всегда именно так, как считает _гуру_, в природе не существует.
В данном конкретном случае человек сказал что ему _проще_ написать проверку. Его стали уверять, что это совсем не проще, проще понаписать кучу врапперов для скрытия кучи кода, потому, что тогда можно будет испльзовать исключения и это будет проще :)
Имхо проще это так, как проще тому кто пишет, а не абстрактному гуру :)
Есть такой старый анекдот.
Сидит чувак, играет. К ниму подходит другой чувак и говорит
— Занялся бы ты чем нибудь полезным
— А зачем?
— Ну напишешь программу ........ организуешь контору, будешь получать деньги и спокойно играть.
— А я что делаю?
Здравствуйте, Alexey Chen, Вы писали:
AC>Здравствуйте, jazzer, Вы писали:
J>>ага J>>макросы и goto — это самое оно AC>А собственно чего плохого в макросах и goto?
Ничего плохого, когда ты находишься в ситуации, что без них не обойтись.
Здесь — не этот случай.
AC>Что они противоречат идее (религии) идеальной программы? AC>Дык, если разговор о сферических конях в вакуме, то я пожалй пойду от сюда. Не силен я в софофилии.
Ничего, если я не буду отвечать на эти выпады?
J>>а ничего, что коды возврата у разных функций могут быть разными? J>>Т.е. одни возвращают int, другие — bool, остальные — свои сотвственные енумы? J>>Как бы выглядела твоя функция?
AC>В конкретном примере, который я назвал вырожденым, ловится инт, а для остальных ошибок происходит утечка ресурсов.
Дело не только в утечке ресурсов?
Это во-первых.
А во-вторых — ответь на поставленный вопрос: Как бы выглядела твоя функция?
AC>Смысл бросать инт?
Смысл не читать реплики собеседника до конца?
Цитирую себя: "А ведь исключением может быть не только захудалый int, а любой класс, который может нести в себе кучу полежной информации, а не только статус."
Этот пример не является вырожденным.
По той простой причине, что этот пример является отражением кода большинства проектов (болшьших, дорогих и серьезных проектов), в которых я работал. Текущий проект — не исключение, более того, у нас запрет на использование исключений из-за того, чтоб проект очень большой и старый, собирается только старым глючным компилятором, в котором исключения реализованы с ошибками — вся команда стонет, выписывая эти бесконечные многоэтажные if.
Очень мало бывает реальных функций типа "чихнуть и выйти".
Обычно там что-нть вроде "позвать девушку на свидание, чихнуть каждой ноздрей, почесаться везде по разу, а потом через раз, поморгать всеми глазами, пощелкать всеми суставами, проверить весь частотный и динамический диапазом своего голоса, и на каждом шаге проверить, не ушла ли девушка".
Так что никаких сферических коней в вакууме.
AC>Если меня не поняли, то я указал на то, что данный пример не является причиной использовать исключения (или не использовать).
J>>Это только если в качестве статуса возвращается bool или нечто к нему приводимое. J>>Ситуация малополезная. J>>В том же COM, насколько я помню, отвал не равен нулю.
AC>В любой программе существует схема обработки ошибок, не обязательно ( или не везде ) на исключениях (или программы очень быстро не существует).
Да, существует. И оборачивается адом для программистов. См. выше.
J>>В том же MFC есть цепочка типа OnPreparePrinting, OnBeginPrinting etc AC>И что из этого следует? Что лучший способ обработки ошибок — это отлов исключений? Имхо, монописсуально.
Лучший способ обработки ошибок в транзакционной логике — отлов исключений.
Большинство реальных функций используют транзакционную логику.
AC>>>Использование механизма исключений требует не только знание самого механизма, но и активное использование RAII там где он не AC>>Без владения RAII, использовать исключения весьма и весьма непросто.
J>>Во-первых, приведенный выше код сравнительно прост, а во-вторых, у тебя будет тот же самый геморрой и с кодами возврата. AC>О чем я собственно и сказал, и исключения там, как козе баян.
приведенный выше — это приведенный тобой, с goto. Будь внимательнее
AC>Еще надо умеючи писать врапперы для вызова функций API/библиотек который ничего о RAII не знают.
Все надо делать умеючи.
Посоревнуемся в трюизмах? AC>Что уже к исключениям имеет самое прямое отношение, так как finally в C++ не предусмотрен.
На тему finally в С++ уже была дискуссия, и я в ней высказался вполне определенно, так что ты споришь не с тем человеком. AC>Имхо, лишняя работа которая обычно нафиг не нужна.
Если у тебя один единственный вызов данной функции API во всей программе — да, это лишняя работа.
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, Alexey Chen, Вы писали: AC>>В конкретном примере, который я назвал вырожденым, ловится инт, а для остальных ошибок происходит утечка ресурсов. J>Дело не только в утечке ресурсов? J>Это во-первых. J>А во-вторых — ответь на поставленный вопрос: Как бы выглядела твоя функция?
Я привел тебе два примера.
Если смущает условие на код ошибки, можно вспомнить, что проверить является возвращенное значение кодом ошибки или нет можно специальным инлайном различающим его тип.
AC>>Смысл бросать инт? J>Смысл не читать реплики собеседника до конца? J>Цитирую себя: "А ведь исключением может быть не только захудалый int, а любой класс, который может нести в себе кучу полежной информации, а не только статус."
Угу, а использовать статическую (ThreadLocal) унифицировнную структуру для хронения информации?
J>Этот пример не является вырожденным. J>По той простой причине, что этот пример является отражением кода большинства проектов (болшьших, дорогих и серьезных проектов), в которых я работал. Текущий проект — не исключение, более того, у нас запрет на использование исключений из-за того, чтоб проект очень большой и старый, собирается только старым глючным компилятором, в котором исключения реализованы с ошибками — вся команда стонет, выписывая эти бесконечные многоэтажные if.
Ну и аргументы у вас WolfHound'ом. А наша команда легко и непринужденно реализуют надежный и прозрачный код и без исключений и даже, страшно подумать, без RAII. И что из этого следует?
И надо заметить не стонут, поскольку это вообще мелочь на которую внимания то осбого не обращают. Всего лишь задача выбора инструмена в заданных условиях. Выбрали и пошли работать. То, что кто-то владеет только исключениями и без них писать не может.... ну, это не аргумент. А многоэтажные ифы... спать больше надо.
J>Имхо, дискуссия стремительно теряет смысл :(
Ее и не было. Просто на мое замечание, о достоинствах исключений в указанном примере, мне стали втирать, что исключения это круто и без них никуда.
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, Alexey Chen, Вы писали:
WH>И опять нет технических аргументов :( WH>Перепиши мой код от сюда без RAII WH>Re[5]: try-catch
Зачем? Для мазахизма?
Текнический аргумент? Ты добавил в код COM логику обработки C++ исключений, и если заменить в твоем коде выброс исключения на выход за пределы блока, ничего не изменится. Следовательно применение исключений в данном коде всего лишь твоя привычка.
Их можно там применять, а можно не применять. Но приводить данный пример как аргумент того, что их там применять НАДО....
У вас, что у тебя, что у jazzer'а, что у A_K очень похожие способы спора. Свести все к чему-то не связанному с вопросом (например умным указателям) и сказать, что точка зрения опонента не верна, потому что без умных указателей, этот конкретный код будет плохим. Если что, мы говорили про исключения и про то, что они требуют испльзовать RAII не только для умных указателей, но для того для чего RAII не предназначен, а именно вызова внешних финализаторов ничего о RAII незнающих.
Еще раз повторю. Я не увидел не от тебя не от jazzer'а примера где их (исключения) НАДО использовать... странно да. Хотя написать такой пример весьма несложно.
Здравствуйте, Alexey Chen, Вы писали:
AC>Еще раз повторю. Я не увидел не от тебя не от jazzer'а примера где их (исключения) НАДО использовать... странно да.
AC>Хотя написать такой пример весьма несложно.
Здравствуйте, Шахтер, Вы писали:
Ш>Здравствуйте, Alexey Chen, Вы писали:
AC>>Еще раз повторю. Я не увидел не от тебя не от jazzer'а примера где их (исключения) НАДО использовать... странно да.
AC>>Хотя написать такой пример весьма несложно.
Ш>Заинтриговали. А можно конкретнее?
Дык, это...
Ситуация когда класс не может быть создан, например ошибка при создании базового класса или агрегата.
Это специфика C++, и изменение такого способа сообщения о ошибке может привести к изменению архитектуры.
Что вобшем-то не есть плохо, но это уже будет совсем другой код.
Ситуация когда возникла ошибка при передаче верменного обьекта куда либо, как другого обьекта. Или отложенные вчисления.
cerr << ost.str().c_str() << endl;
или
com_object1->oproperty1->DoAnythingWithBSTR("text");
Разруливается и без исключений, но может серьезно ухудшить жизнь.
Ситуация когда нужен откат через много уровней вложенности. Например парсер без восстановления после ошибки.
Можно и через код возврата, но специфика такая, что это не последовательность действий которую надо прервать, а иерархия из которой надо выйти.
Это то, что первое в голову пришло, но думаю не единственное.
А прервать последовательность исполнения функций можно и без исключенй. Тут уже дело привычки.
Здравствуйте, Alexey Chen, Вы писали:
AC>Здравствуйте, Шахтер, Вы писали:
Ш>>Здравствуйте, Alexey Chen, Вы писали:
AC>>>Еще раз повторю. Я не увидел не от тебя не от jazzer'а примера где их (исключения) НАДО использовать... странно да.
AC>>>Хотя написать такой пример весьма несложно.
Ш>>Заинтриговали. А можно конкретнее?
AC>Дык, это...
AC>Ситуация когда класс не может быть создан, например ошибка при создании базового класса или агрегата. AC>Это специфика C++, и изменение такого способа сообщения о ошибке может привести к изменению архитектуры. AC>Что вобшем-то не есть плохо, но это уже будет совсем другой код.
+)
AC>Ситуация когда возникла ошибка при передаче верменного обьекта куда либо, как другого обьекта. Или отложенные вчисления. AC>cerr << ost.str().c_str() << endl; AC>или AC>com_object1->oproperty1->DoAnythingWithBSTR("text"); AC>Разруливается и без исключений, но может серьезно ухудшить жизнь.
+)
AC>Ситуация когда нужен откат через много уровней вложенности. Например парсер без восстановления после ошибки. AC>Можно и через код возврата, но специфика такая, что это не последовательность действий которую надо прервать, а иерархия из которой надо выйти.
+)
AC>Это то, что первое в голову пришло, но думаю не единственное.
AC>А прервать последовательность исполнения функций можно и без исключенй. Тут уже дело привычки.
Можно сказать -- острой необходимости нет.
Хороший набор примеров. Мне как-то в голову сразу не пришло ничего.
Здравствуйте, Alexey Chen, Вы писали:
AC>А прервать последовательность исполнения функций можно и без исключенй. Тут уже дело привычки.
А вот тебе ещё один пример за исключения, а не код возврата в любом случае...
Пример 1:
int SomeObj::get_val()
{
int val = 0;
// делаем полезную работу, при ошибке выкидываем исключенияreturn val;
}
//...try
{
int val = obj->get_val();
}
catch(...)
{
std::cerr << "Произошла ошибка" << std::endl;
}
Пример 2:
ErrCode SomeObj::get_val(int *retVal)
{
ErrCode code = ErrFail;
if(retVal != 0)
{
int val = 0;
// делаем полезную работу, при ошибке передаём управление на точку выхода
retVal = val;
code = ErrOk;
}
return code;
}
//...int val;
ErrCode code = obj->get_val(&val);
if(code == ErrOk)
{
}
else
{
std::cerr << "Произошла ошибка" << std::endl;
}
Вот даже если посчитать в строчках кода то первый пример сурово короче... Написать врапперы можно один раз и использовать их везде, а если с goto, кодами возвратов и врапперами, то придётся лабать код наподобие примера 2 каждый раз...
Лично я выбираю вариант 1.
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Здравствуйте, Mr. None, Вы писали:
MN>Здравствуйте, Alexey Chen, Вы писали:
AC>>А прервать последовательность исполнения функций можно и без исключенй. Тут уже дело привычки.
MN>Вот даже если посчитать в строчках кода то первый пример сурово короче...
Что-то у меня не получается сурово короче. Это в строчках. А если в тактах, то это ещё бабушка на двое сказала, что лучше, потому что невинно выглядящий try на самом деле кое-что делает.
Реальная экономия тут будет, если в блоке try catch серия таких вызовов.
MN>Написать врапперы можно один раз и использовать их везде, а если с goto, кодами возвратов и врапперами, то придётся лабать код наподобие примера 2 каждый раз... MN>Лично я выбираю вариант 1.
Здравствуйте, Alexey Chen, Вы писали:
AC>Если в программе нет шаблонов и исключений — это С с классами. Язык пионэров? Мачто на нем непушут, да?
Совсем нет. Язык C — прекрасный язык в рамках структурной парадигмы программирования. Писать на нём тоже надо уметь: структурный подход — это вам тоже не в тапки писать, пионэрам не осилить (загляните в код ядра W2K и вы поймёте о чём я говорю).
А вот что делают пионэры и делают очень зря — это смешивают парадигмы структурную и объектно-ориентированную (то что вы называете C с классами). При этом возникают не сферические кони в вакууме, а вполне конкретные проблемы, одна из которых, например, — это доказательство правильность ПО. Подходы к решению этой проблемы в структурном и объектно-ориентированном программировании различные. И смешивая в своей программы разные стили вы запутываете этот процесс. А есть ещё проблемы проектирования архитектуры, сбора требований и многое многое другое.
И ещё один комментарий.. Можно вообще писать так:
main()
{
asm
{
...
}
}
но ведь никто так не делает...
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Здравствуйте, Шахтер, Вы писали:
Ш>Здравствуйте, Mr. None, Вы писали:
MN>>Здравствуйте, Alexey Chen, Вы писали:
AC>>>А прервать последовательность исполнения функций можно и без исключенй. Тут уже дело привычки.
MN>>Вот даже если посчитать в строчках кода то первый пример сурово короче...
Ш>Что-то у меня не получается сурово короче. Это в строчках. А если в тактах, то это ещё бабушка на двое сказала, что лучше, потому что невинно выглядящий try на самом деле кое-что делает. Ш>Реальная экономия тут будет, если в блоке try catch серия таких вызовов.
В строчках:
пример 1 — 14
пример 2 — 21
И это только для одной функции.
Реалии современного ИТ-мира таковы, что работа программиста стоит дороже нового процессора. Поэтому проблему производительности проще решать заменой вычислительной базы, а не оптимизацией, ведущей к усложнению читабельности кода.
Такты считали в конце позапрошлого десятилетия, сейчас считают деньги. Никто не будет платить за доработку программы столько же, сколько за её разработку. А чтобы дорабатывать программу (читай сопровождать) было проще, она должна быть как минимум понятна и легко читаема сопровождающим программистом.
Какой вариант лучше читаем? IMHO тот, где меньше строчек, прозрачнее переходы, понятнее названия и читабельнее сигнатуры.
Чтобы меня не обвинили в отсутствии конкретики, привожу реальный пример.
У меня был опыт, когда клиент (немец) выдал исходники и сказал: писать заново дорого и долго, а проекты похожы, давай-ка отталкиваясь от имеющихся исходников напиши то, что мне надо... Код представлял из себя какую-то мешанину из подходов, стилей и пр. и др., изабиловал непонятными goto и чёрт знает чем ещё... У меня ушло на "доработку" недели 3, причём приложение было очень нестабильным. На следующем проекте я сказал этому клиенту — я буду писать заново, из старого буду использовать только пару библиотек. На разработку с нуля у меня ушло 2 недели, хотя проект был сурово сложнее. Потом модификацией данного кода было создано ещё 2 проекта примерно за неделю каждый — один делал я, другой мой приемник. Жалоб на них не было. Выводы делайте сами.
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
На самом деле, фокус там не в том, как работает, а в том, когда использовать. Решить, что должна функция делать в результате ошибки — возвращать соответствующий код возврата или бросать исключение не всегда просто, особено если разрабатываешь универсальный код.
Хороший пример — оператор new. Почему он бросает исключение, а не возвращает NULL в случае неуспеха? Мне кажется, по двум причинам:
1) ситуация достатчно редкая, значит вставлять проверку в виде if после каждого вызова нерационально
2) сделать что-либо разумное в этом случае зачастую нельзя — значит, в случае сбоя остается только вывести сообщение и завершить программу. А для этого будет достаточно самого "большого" try в начале программы.
А вот, например, функция открытия файла. Обратный пример. Ошибка открытия файла совершенно не должна приводить к возникновению исключения — мало ли что будет сделано потом, может не открылся — и ладно, новый выберем, а ситуация это распространенная. Дело в том, что синхронизовать выполнение программы после исключения с "нормальным" зачастую бывает непросто.
Здравствуйте, Mr. None, Вы писали:
MN>Здравствуйте, Alexey Chen, Вы писали:
AC>>Если в программе нет шаблонов и исключений — это С с классами. Язык пионэров? Мачто на нем непушут, да?
MN>Совсем нет. Язык C — прекрасный язык в рамках структурной парадигмы программирования. Писать на нём тоже надо уметь: структурный подход — это вам тоже не в тапки писать, пионэрам не осилить (загляните в код ядра W2K и вы поймёте о чём я говорю). MN>А вот что делают пионэры и делают очень зря — это смешивают парадигмы структурную и объектно-ориентированную (то что вы называете C с классами). При этом возникают не сферические кони в вакууме, а вполне конкретные проблемы, одна из которых, например, — это доказательство правильность ПО. Подходы к решению этой проблемы в структурном и объектно-ориентированном программировании различные. И смешивая в своей программы разные стили вы запутываете этот процесс. А есть ещё проблемы проектирования архитектуры, сбора требований и многое многое другое.
Для начала давайте не будем смешивать проектирование и программирование, вещи конечно связанные, но не так как вы написали.
Кстати, где вы на практике видели доказательство правильности работы ПО? Вопрос чисто из интереса.
Во-вторых:
C с классами как золушка индустрии программирования, множество проектов делается именно на этом языке но формально считается что писать на нем зазорно и идеологически неверно.
Имхо, в процессе становления C++ выработался язык более простой чем C++ (народный так сказать), более дешовый при применении в разработке чем C или С++, менее требовательный к железу и компиляторам чем pure С++. Этот язык результат естественной эволюции. Можно конечно его отрицать и говорить что мы, мачо, на такой фигне не пишем. Пользуемся только OO или только структурным программированием. И вообще видим только черное и белое. Только действительность то цветная.
Компиляторы тоже разные бывают. Если данный компилятор не поддерживает исключения и частичную специализацию будем писать на C?
Стоит ли из за таких мелочей от RAII и параметризации отказываться?
Тут кто-то заметил, что стоимость работы программиста стоит дороже процессора. Это смотря какие программы писать. Если у вас конкретная железка например XBox, то вы не в силах повлиять на процессор. Если вы пишете софтину управляющую железом, которое потом пойдет в серию в оооочень большом количестве, то стоимость работы программиста, это сильно обсуждаемая вешь.
Здравствуйте, Alexey Chen, Вы писали:
AC>Для начала давайте не будем смешивать проектирование и программирование, вещи конечно связанные, но не так как вы написали.
Опишу собственный опыт "смешения". Писал я на Pascal Oregon SoftWare на PDP-11 ЕСКД-докуметратор. Постановка была очень хорошая — все рамочки выверены до милиметра (а печатать, кто помнит, надо было на АЦПУ ). Я поступил очень просто. Исходный текст документа представлял собой текстовый файл, редактируемый редакторм TED через диплей. В текстовый файл вставлялись управляющие операторы вроде "Раздел", "Подраздел", "Содержание" и так далее. Прогриамма читала файл с управляющими операторами и выдавала "выстроенный" по ЕСКД в рамочках документ тоже в виде файла, который оставалось только напечатать. Совершенно типичный подход для того времени и того ПО.
Естественно — основная работа — со строками, которых в том паскале — не было, поэтому я реализовал собственные. На входе-то строки переменной длины, а на выходе — фиксированной! — по ширине рамочки! И черт меня дернул (блин, конечно это был программистский змей-искуситель — эффективность) сделать второй вид строк — для выходного документа. Сейчас я могу только над собой. А тогда мне было не до смеха — я проклял все на свете, отлаживая два механизма строк да еще и преобразовыания между ними. С тех пор я понял: "смешивать" в программировании что бы то ни было — категорически не рекомендуется!
AC>Кстати, где вы на практике видели доказательство правильности работы ПО? Вопрос чисто из интереса.
Мой дипломник доказал правильность разработанных программ собственного диплома. В промышленности, действительно, не видать. AC>Во-вторых: AC>C с классами как золушка индустрии программирования, множество проектов делается именно на этом языке но формально считается что писать на нем зазорно и идеологически неверно.
А ерунда! Писать можно на чем угодно, лишь бы работало. И программы сдавались в срок.
AC>Имхо, в процессе становления C++ выработался язык более простой чем C++ (народный так сказать), более дешовый при применении в разработке чем C или С++, менее требовательный к железу и компиляторам чем pure С++. Этот язык результат естественной эволюции. Можно конечно его отрицать и говорить что мы, мачо, на такой фигне не пишем. Пользуемся только OO или только структурным программированием. И вообще видим только черное и белое. Только действительность то цветная.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Те же 14 строчек.
MN>И это только для одной функции.
MN>Реалии современного ИТ-мира таковы, что работа программиста стоит дороже нового процессора.
У разных людей разные реалии. Тут всё зависит от процессора. Да и программисты бывают китайские.
MN>Поэтому проблему производительности проще решать заменой вычислительной базы, а не оптимизацией, ведущей к усложнению читабельности кода.
Не всегда проще. Более того, если ты вспомнишь, например, мощность процессора, летавшего недавно на Марс, то поймешь, что в некоторых случаях просто невозможно (кстати, сколько этот процессор стоил, с учетом доставки, а?).
MN>Такты считали в конце позапрошлого десятилетия, сейчас считают деньги.
На самом деле, и тогда, и сейчас считают деньги.
MN>Никто не будет платить за доработку программы столько же, сколько за её разработку.
ХЗ. Всякое бывает.
MN>А чтобы дорабатывать программу (читай сопровождать) было проще, она должна быть как минимум понятна и легко читаема сопровождающим программистом.
Золотые слова. К сожалению, реальность очень часто не следует им.
MN>Какой вариант лучше читаем? IMHO тот, где меньше строчек, прозрачнее переходы, понятнее названия и читабельнее сигнатуры. MN>Чтобы меня не обвинили в отсутствии конкретики, привожу реальный пример. MN>У меня был опыт, когда клиент (немец) выдал исходники и сказал: писать заново дорого и долго, а проекты похожы, давай-ка отталкиваясь от имеющихся исходников напиши то, что мне надо... Код представлял из себя какую-то мешанину из подходов, стилей и пр. и др., изабиловал непонятными goto и чёрт знает чем ещё... У меня ушло на "доработку" недели 3, причём приложение было очень нестабильным. На следующем проекте я сказал этому клиенту — я буду писать заново, из старого буду использовать только пару библиотек. На разработку с нуля у меня ушло 2 недели, хотя проект был сурово сложнее. Потом модификацией данного кода было создано ещё 2 проекта примерно за неделю каждый — один делал я, другой мой приемник. Жалоб на них не было. Выводы делайте сами.
Здравствуйте, Vamp, Вы писали:
V>На самом деле, фокус там не в том, как работает, а в том, когда использовать. Решить, что должна функция делать в результате ошибки — возвращать соответствующий код возврата или бросать исключение не всегда просто, особено если разрабатываешь универсальный код. V>Хороший пример — оператор new. Почему он бросает исключение, а не возвращает NULL в случае неуспеха? Мне кажется, по двум причинам: V>1) ситуация достатчно редкая, значит вставлять проверку в виде if после каждого вызова нерационально V>2) сделать что-либо разумное в этом случае зачастую нельзя — значит, в случае сбоя остается только вывести сообщение и завершить программу. А для этого будет достаточно самого "большого" try в начале программы. V>А вот, например, функция открытия файла. Обратный пример. Ошибка открытия файла совершенно не должна приводить к возникновению исключения — мало ли что будет сделано потом, может не открылся — и ладно, новый выберем, а ситуация это распространенная. Дело в том, что синхронизовать выполнение программы после исключения с "нормальным" зачастую бывает непросто.
Исключения хороши для обработки ошибок класса авария. В тех случаях, где остаётся только грести побыстрому до ближайшей удобной бухты. А в остальных случаях -- делеко не факт.
Ошибки ввода пользователя, например. Логично переспросить неверно введённые данные.
Здравствуйте, Alexey Chen, Вы писали:
AC>Для начала давайте не будем смешивать проектирование и программирование, вещи конечно связанные, но не так как вы написали.
Они связаны очень сильно, даже больше чем вам кажется — все методы проектирования ориентированы на ту или иную парадигму программирования (они даже по названиям разделяются аналогично — методы структурного проектирования, методы объектно-ориентированного проектирования). Вот если связи между проектированием и программированием нет, то и получается C с классами.
AC>Кстати, где вы на практике видели доказательство правильности работы ПО? Вопрос чисто из интереса.
В случае структурного программирования только в университете. Для структурного программирования применяются формально-математические методы (не знаю применяют ли их в промышленности хотя бы ограниченно). Я не считаю себя знатоком структурного подхода, поэтому в реальной жизни этим методом и такими способами доказательства не пользовался.
В случае ООП эту задачу решаю регулярно. В силу определённых причин (в числе которых сама идеология ООП и сложность разрабатываемых в этой идеологии проектов) достаточными условиями доказательства правильности ПО, написанного с использованием объектно-ориентированной парадигмы, являются:
1) соблюдение всем приложением высокоуровневых требований заказчика;
2) соблюдение объектами системы контрактов системного уровня.
Залогом выполнения этих требований является грамотное проектирование и ведение проектной документации (к которой относится и код) в течении всего времени разработки. Техническими способами проверки являются, например, такие механизмы, как:
1) грамотное, однозначное и безопасное оформление интерфейсов, например, расстановка модификаторов const, спецификация списка исключений и т.д. и т.п.
2) проверка пред- и пост- условий обработки сообщений, она не реализована на уровне языка C++, так как например в языке Efiel, но может быть запросто реализована на уровен библиотек;
3) всеобъемлющее тестирование, в случае использования полных юнит-тестов для каждого класса системы возможен отказ от пункта 2.
AC>C с классами как золушка индустрии программирования, множество проектов делается именно на этом языке но формально считается что писать на нем зазорно и идеологически неверно.
В больших проектах использование такого подхода чревато. Даже когда пишешь на красивом и чистом C++ не удаётся избежать проблемы разрастания и избыточности кода, приходится делать рефакторинг, при этом сталкиваешься с кучей проблем, то в случае C с классами — это вообще может привести к смерти проекта.
AC>более дешовый при применении в разработке чем C или С++,
Вот тут согласен — студентам действительно платят меньше, чем гуру с 15-ти летним опытом
AC>менее требовательный к железу и компиляторам чем pure С++.
Насчёт компилятора — согласен, насчёт железа — нет, вспомни хотя бы пример Мейерса из книги "Эффективное использование STL" со сравнением быстродействия сортировок с помощью функции CRT qsort и алгоритма std::sort...
AC>Можно конечно его отрицать и говорить что мы, мачо, на такой фигне не пишем. Пользуемся только OO или только структурным программированием. И вообще видим только черное и белое. Только действительность то цветная.
Мачо себя не считаю, но пишу только на ООП, стараюсь использовать чистый C++ и вижу действительность в цветных радужных тонах — проблем от этого никаких не испытываю.
AC>Компиляторы тоже разные бывают. Если данный компилятор не поддерживает исключения и частичную специализацию будем писать на C?
Нет — поменяем компилятор.
AC>Тут кто-то заметил, что стоимость работы программиста стоит дороже процессора. Это смотря какие программы писать. Если у вас конкретная железка например XBox, то вы не в силах повлиять на процессор. Если вы пишете софтину управляющую железом, которое потом пойдет в серию в оооочень большом количестве, то стоимость работы программиста, это сильно обсуждаемая вешь.
ИМХО очень неудачный пример, на одном из поектов мы писали прошивку для микроконтроллеров на чистом C++, проблем никаких не было.
Кстати, даже прошивку для BIOS`а на ассемблере можно писать с ипользованием объектно-ориентированной парадигмы, правда это очень сложно.
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.