Здравствуйте, AndreyFedotov, Вы писали:
AF> Мы тут чудненько пофлеймили на тему "о применимости С++ в серьёзном коде" , но как то за кадром остался вопрос о том, что же такое "серьёзный код". Были правда некоторые попытки определить это понятие, но они быстро иссякли. AF> А вы как думаете — какой код можно назвать "серъёзным" или "сложным"? Как Вы вообще — разделяете ли код по каким-либо критериям и на какие то категории? И если да, то по каким?
Я склоняюсь к мысли, что "серьезность" кода больше определяется его назначением, областью применения и т.п., нежели непосредственно его содержанием, например:
Делаем форму, кидаем не нее кучу контролов разных навороченных и делаем какую-нить процедуру отображения даных из БД на эту форму.
"Серьезный" код — если это используется в программе управления космическим кораблем или в программе управления биржевыми торгами.
Не "серьезный" код — все это написано для сдачи зачета в институте.
Другими словами, можно сказать, что чем больше отвественность лежит на коде, тем "серьезнее" код.
"Сложность" кода — это исходя их каких параметров оценки смотреть: сложность понимания, кодирования, поддержки, модификации и т.п.
З.Ы. Сложнее всего написать простой код -> "сложный" код — это есть простой код
Здравствуйте, AndreyFedotov, Вы писали:
AF> Мы тут чудненько пофлеймили на тему "о применимости С++ в серьёзном коде" , но как то за кадром остался вопрос о том, что же такое "серьёзный код". Были правда некоторые попытки определить это понятие, но они быстро иссякли.
Правильно сказали что есть разница между серьезным и сложным. Серьезность кода это серьезности задачи, а серьезность задачи вообще управленческая область.
Про сложность и классификации . Если не брать в расчет предметную область, то тогда получается 2 измерения: слабая/сильная детерминированность, слабая/сильная абстрактность. Хотя может показаться что это что-то близкое, я думаю что нет. Если же взять еще и предметную область (живем же в реальном мире), то тогда 3 измерение — специфичность этой области.
Про детерминированность хочеться сказать то, что чем она больше, тем ближе к машине (скорость, память...) но зато и дальше от человека. При всем при том что и сильная и слабая может писаться на одном языке, сильная выглядит страшнее ассемблера. Выбрасываются строки, там где это можно, всякие универсальные коллекции заменяются типизированными или массивами, красивое с точки зрения дизайна заменяется на некрасивое но производительное. Такая вот селяви.
Здравствуйте, Alex Reyst, Вы писали:
AR>Серьезный код — код, который не вызывает приступов истерического смеха у серьезного программиста. (Желающие дать определение термину "серьезный программист" — welcome во флейм или юмор).
Не знаю, могу ли я считать себя серьезным программистом, но однажды мне принесли код и я буквально чуть не помер от смеха. Подозвал коллег, и они тоже чуть не уписались. Код был очень несерьезный
Здравствуйте, AndreyFedotov, Вы писали:
AF>>>для меня "серъёзный" код — это код со сложной архитектурой и множеством взаимосвязей и взаимозависимостей.
AR>>А вот это бы я назвал именно сложным кодом.
AF> Иногда да, иногда нет. В таких системах часто сам код очень простой, но именно наличие множества скрытых и не очевидных связей делает его написание делом не простым.
Может просто проблема проектирования? Код должен быть простым для понимания, тогда это хороший код. Смотря, конечно, для кого простым На асме писать очень просто, но при сложном алгоритме (да и просто по мере разбухания проекта, если его правильно не спроектировать) получается как раз такой "серьезный", по-твоему определению, код. На ЯВУ же этого запутывания имхо можно избежать.
Re[2]: Пример не серьезного и аналогичного ему серьезного ко
Здравствуйте, shev, Вы писали:
S>В данном серьезном коде допущена серьезная ошибка. Создание объекта TIniFile должно быть вынесено из блока try..finally
Да что Вы такое говорите! Да неужели? Правда что ли??? А если подумать?
А что если допустить такую крамольную мысль, что исключительная ситуация может быть возбуждена внутри конструктора или даже перед конструированием (память кончилась), тогда что?
Код:
f := NIL;
TRY
f := TMyObject.Create(SomeObj.GetParameters());
f.DoSmth();
FINALLY
f.Free();
END;
остается безопасным в обоих случаях:
1) Объект еще не успел создаться, т.е. f = NIL (это из-за того что Free перед вызовом деструктора проверяет Self на равенство NIL),
2) Объект уже успел создаться — в FINALLY уничтожаем его
Re[4]: Пример не серьезного и аналогичного ему серьезного ко
Здравствуйте, S.Yu.Gubanov, Вы писали:
SYG>А что если допустить такую крамольную мысль, что исключительная ситуация может быть возбуждена внутри конструктора или даже перед конструированием (память кончилась), тогда что?
Тогда объект TMyObject не создастся и освобождать объект методом Free() не требуется. Произойдет обычное прерывание из-за произошедшего исключения.
SYG>1) Объект еще не успел создаться, т.е. f = NIL (это из-за того что Free перед вызовом деструктора проверяет Self на равенство NIL), SYG>2) Объект уже успел создаться — в FINALLY уничтожаем его
Общий принцип работы с исключениями:
obj := TMyObject.Create();
//создаем объект, если в процессе создания произошло исключение (объект не создастся), то
//просто вывалимся до ближайшей обработки исключения верхнего уровня. try//что-то делаем с объектом obj, что может вызвать иcключениеfinally
obj.free;
//освобождаем объект и опять же вываливаемся до ближайшей обработки исключения верхнего уровняend
Конечно, Ваш вариант абсолютно работоспособен и я поспешил утверждать что он содержит серьезную ошибку, т.к. как Вы уже написали выше "Free перед вызовом деструктора проверяет Self на равенство NIL".
Хотя...
Пришла мысль. Вот код, в котором Вас стиль использования исключений будет неправильным, и даже приведет к серьезной ошибке, которую не так очевидно будет обнаружить:
TMyClass=class(TObject)
public
constructor Create(OpenFileName: string);
end;
procedure OpenManyFiles(ListFiles: TList);
var
obj: TMyClass;
begin
try
obj:=TMyClass.Create('FirstFileName');
ListFiles.Add(obj);
finally
obj.Free;
end;
try
obj:=TMyClass.Create('SecondFileName');
ListFiles.Add(obj);
finally
obj.Free;
end;
end;
Процедура OpenManyFiles открывает несколько файлов и сохранят объекты их обслуживающие в списке файлов ListFiles.
Возьмем случай, когда открытие первого файла прошло успешно, а второго 'SecondFileName' нет.
Тогда obj до вызова конструктора
obj:=TMyClass.Create('SecondFileName');
будет содержать ссылку на первый файл. Когда произойдет исключение, то в блоке finally вызовется метод Free для obj первого файла!, ссылка на который уже давно лежит в списке ListFiles и в последствии будет использоваться другим кодом. Т.е. новая ошибка затаится до момента, когда кто-то захочет пробежаться по элементам списка ListFiles. А наступить это может через большой промежуток времени, в абсолютно далеком месте программы и найти концы будет очень сложно.
Конечно можно избежать данной ситуации, если между открытиями первого и второго файла дописать obj:=nil, но это можно забыть сделать.
В случае же если создание объекта вынесено из блока try..finally (всегда считал это классическим способом), описанной выше проблемы просто не произойдет. И такой способ является абсолютно безопасным.
Re[5]: Пример не серьезного и аналогичного ему серьезного ко
Я согласен с Вами в том, что код, который я привел
f := NIL;
TRY
f := TMyObject.Create();
//...FINALLY
f.Free;
END;
действительно может содержать грубейшую ошибку, но только в том случае если забыть написать инструкцию f := NIL. Постольку поскольку, я ее написать не забыл, то приведенный код не содержит ошибки. Что Вы накинулись -"Ошибка, Ошибка!!". Нет ошибки-то. О чем весь сыр бор? Может закончим на этом?
Я могу объяснить почему я использую именно такую конструкцию. Поначалу я тоже писал TRY после, а не до создания объекта, но потом перешел на этот стиль потому что, часто создаю несколько объектов (бывает даже по 10-15 штук):
a := NIL; b := NIL; c := NIL;
TRY
a := TAaa.Create();
b := TBbb.Create();
c := TCcc.Create();
//...совместное использование объектов a,b,cFINALLY
a.Free; b.Free; c.Free;
END;
Если бы я писал TRY после, то пришлось бы вкладывать блоки TRY FINALLY друг в друга:
a := TAaa.Create();
TRY
b := TBbb.Create();
TRY
c := TCcc.Create();
TRY//...совместное использование объектов a,b,cFINALLY
c.Free;
END;
FINALLY
b.Free;
END;
FINALLY
a.Free;
END;
код от этого раздувается, поэтому я так и не пишу, а пишу так как показал в самом начале.
Re[6]: Пример не серьезного и аналогичного ему серьезного ко
Здравствуйте, AndreyFedotov, Вы писали:
AF> Мы тут чудненько пофлеймили на тему "о применимости С++ в серьёзном коде" , но как то за кадром остался вопрос о том, что же такое "серьёзный код". Были правда некоторые попытки определить это понятие, но они быстро иссякли. AF> А вы как думаете — какой код можно назвать "серъёзным" или "сложным"? Как Вы вообще — разделяете ли код по каким-либо критериям и на какие то категории? И если да, то по каким? AF> Наверняка у каждого из нас своя точка зрения по этому поводу. Предлагаю поделиться...
Серьезный код — это код, который делается не дял себя. Например, диплом. Это уже серьезно, так как диплом надо защищать и демонстрировать работоспособность системы. Если вы мне скажете, что диплом никто не читает, так вы ошибетесь — я читаю.
В общем, серьезный код — это код, оттогаемый от разработчика и используемый другими людьми.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, LaptevVV, Вы писали:
LVV>Здравствуйте, AndreyFedotov, Вы писали:
AF>> Мы тут чудненько пофлеймили на тему "о применимости С++ в серьёзном коде" , но как то за кадром остался вопрос о том, что же такое "серьёзный код". Были правда некоторые попытки определить это понятие, но они быстро иссякли. AF>> А вы как думаете — какой код можно назвать "серъёзным" или "сложным"? Как Вы вообще — разделяете ли код по каким-либо критериям и на какие то категории? И если да, то по каким? AF>> Наверняка у каждого из нас своя точка зрения по этому поводу. Предлагаю поделиться... LVV>Серьезный код — это код, который делается не дял себя. Например, диплом. Это уже серьезно, так как диплом надо защищать и демонстрировать работоспособность системы. Если вы мне скажете, что диплом никто не читает, так вы ошибетесь — я читаю. LVV>В общем, серьезный код — это код, оттогаемый от разработчика и используемый другими людьми.
Серьезность кода и диплом не имееют ничего общего, по крайней мере везде где я знаю так оно и есть. Я знаю такие дипломные работы, котрые даже на лабораторную для 1-ого курса не потянут. А код которых и глядеть страшно.
ЗЫ: Исключения бывают конечно, но это именно исключения, а не правила.
Re[7]: Пример не серьезного и аналогичного ему серьезного ко
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, S.Yu.Gubanov, Вы писали:
WH>Кстати классный пример того почему С++ рулит... WH>
WH>Taaa a;
WH>Tbbb b;
WH>Tccc c;
WH>...
WH>
WH>
Ну это быстренько можно "подпортить", и "рульность" С++ поубавится
1) Пусть a,b,c — это очень большие объекты, так что на стеке втроем им места не хватит...
2) Пусть a,b,c — это не объекты, а полиморфные переменные. В терминологии С++ статический тип a,b,c — пусть будет указатели на объекты "абстрактных классов". Так как в стандартном С++ есть только блок try catch, а FINALLY — нету, то жизнь сразу усложняется. Придется использовать классы обертки — "умные указатели", а это уже из другой оперы.
Здравствуйте, Denwer, Вы писали:
D>Серьезность кода и диплом не имееют ничего общего, по крайней мере везде где я знаю так оно и есть. Я знаю такие дипломные работы, котрые даже на лабораторную для 1-ого курса не потянут. А код которых и глядеть страшно.
D>ЗЫ: Исключения бывают конечно, но это именно исключения, а не правила.
Ну так у нас сплошные исключения
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[8]: Пример не серьезного и аналогичного ему серьезного ко
Здравствуйте, S.Yu.Gubanov, Вы писали:
SYG>Придется использовать классы обертки — "умные указатели", а это уже из другой оперы.
Ну почемуже из другой оперы? Очень даже из тойже самой... Автоматические деструкторы рулят
Затараты памяти и производительность не изменятся.
Хотя я обычно использую объекты с интрузивным подсчетом ссылок.
SYG>Вот уж кто в таких случаях на самом деле по взрослому рулит, так это (компилируемый) язык со сборщиком мусора и без "исключительных ситуаций", например, Component Pascal (http://www.inr.ac.ru/~info21/cpascal/cp_report_1.4_rus.htm)
Практика показывает что очень часто от ГЦ поблем больше чем пользы. Тк время уничтожения объекта недетерминировано то возникает проблема с освобожедением внешних ресурсов.
А отсутствие исключений это гемор тот еще... Попробуй вернуть ошибку на 10 уровней наверх без исключений...
Короче мертворожденный продукт. Он не сможет конкурировать ни С++ на полу С++ ни с .НЕТ на полу .НЕТ. Ибо и тому и другому проигрывает по возможностям. Накой это язык вобще нужен не понятно.
... << RSDN@Home 1.1.3 beta 1 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[9]: Пример не серьезного и аналогичного ему серьезного ко
Здравствуйте, WolfHound, Вы писали:
WH>Практика показывает что очень часто от ГЦ поблем больше чем пользы. Тк время уничтожения объекта недетерминировано то возникает проблема с освобожедением внешних ресурсов.
Какие проблемы?
WH>А отсутствие исключений это гемор тот еще... Попробуй вернуть ошибку на 10 уровней наверх без исключений...
Зачем возвращать ошибку?
WH>Короче мертворожденный продукт. Он не сможет конкурировать ни С++ на полу С++ ни с .НЕТ на полу .НЕТ. Ибо и тому и другому проигрывает по возможностям. Накой это язык вобще нужен не понятно.
Странный Вы. Component Pascal-ю более 10 лет между прочим.
Просто когда есть Сборщик мусора, проектировать все надо совершенно по другому, а это как-то непривычно.
Мысли на счет исключений:
Исключения бывают "вредные" — то есть те которые и быть-то не должны — они сигнализируют о сбое работы программы, если они возникают, значит программа написана криво; а бывают "полезные" — это те исключения, которых ожидают и обрабатывают согласно логике работы программы, они заранее были запланированы. Так вот в Component Pascal так сказать "вредные" исключения (выход индекса за пределы массива, неправильное приведение типа, не предусмотренный вариант выбора в инструкции CASE и т.п.) — просто автоматически немедленно останавливают работу программы и все — программиста на мыло! А все "полезные" исключения всегда можно реализовать вовсе каким-нибудь другим способом, а не через собственно механизм исключений, если подумать конечно. Так что механизм исключений излишен.
Re[10]: Пример не серьезного и аналогичного ему серьезного к
Здравствуйте, S.Yu.Gubanov, Вы писали:
SYG>Какие проблемы?
Открыли фаил, поработали и забыли, открыли еще один фаил поработали и забыли... тк время уборки мусора недетерминировано открытых файлов скопится может очень много... и не исключен вариант что у системы закончатся лимит открытых файлов и все...
Вот только не надо мне втирать что я должен помнить о том что я открыл фаил... Во первых я ни кому ни чего не должен, во вторых я человек и могу забыть, в третьих любимый тобой С++ помнит это за меня.
SYG>Зачем возвращать ошибку?
А что мне делать если пользователь ввел не верные данные?
SYG>Странный Вы. Component Pascal-ю более 10 лет между прочим.
Если он такой крутой и ему уже 10 лет то почему на нем никто не пишет?
SYG>Мысли на счет исключений:
Во первых о вредных исключениях надо расказать все что можно для того чтобы было легче устранить ошибку.
Во вторых на кой черт извращатся если можно кинуть исключение?
Мне влом выписывать и еще болие влом читать что-то типа:
А если логика алгоритма сложная то за обработкой ошибок с которыми на этом уровне всеравно ни чего не сделать можно потерять сам алгоритм.
А если еще учесть что исключения это классы, а их можно наследовать то допустим мы можем сделать file_exception и отнаследовать от него open_file_exception, read_file_exception... теперь нам фиолетово какое именно из этих исключений вылетело мы их все можем поймать при помощи catch(file_exception const& ex). А теперь сделай тоже самое на кодах возврата.
И самое веселое если в некоторой подсистеме может происходить несколько типов ошибок (проблемы с файлами, сетью, пользователем...) что ты тогда будешь делать с кодами возврата?
... << RSDN@Home 1.1.3 beta 1 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн