Здравствуйте, AndrewVK, Вы писали:
CC>>Вот мне всегда было непонятно, почему в плюс языка всегда пытаются отнести большую стандартную библиотеку? AVK>Потому что хороший современный язык обязан быть спроектирован в том числе и с учетом простоты и удобства как создания фреймворков, так и их использования. А для С++ даже ABI все никак не устаканят.
Нестабильный ABI в С++ уже перешёл из состояния "бага" в состояние "фича".
Здравствуйте, MasterZiv, Вы писали:
MZ>Чтобы в Java НЕ ЖДАЛИ появления RuntimeException, которое по сути своей MZ>непредсказуемо появляется, -- это новость какая-то.
Пардон, то есть ты хочешь сказать, что RuntimeException в java ждут всегда? Вот это на самом деле новость-то.
Здравствуйте, opener, Вы писали:
O>Насколько сложно перейти на Java после С++? Проще/сложнее сама жаба по сравнению с С++?
Зависит от головы. Кто-то знает десятки очень разных языков, а кто-то освоил один кое-как и на большее не способен.
Чем больше ты знаешь языков и чем более разнообразны языки которые ты изучил и умеешь применять, тем лучше для тебя и твоего работодателя. Причем совершенно все равно на каком языке ты будешь программировать в ближайшем будущем. Ты все равно будешь мыслить шире.
O>По моим нынешним представлениям вроде проще.
Трикритические размышления ничего не значат. Изучи, а потом рассуждай.
O>И какого тогда хрена у жаба-программистов зарплаты больше?
Хороший С++-программист имеет хорошую зарплату Хороший ява-программист имеет тоже хорошую зарплату. Плохая разплата определяется исключительно двумя факторами:
1. Бездарностью личности.
2. Спросом на программистов в конкретном месте в конкретное время.
Оба фактора при желании поддаются изменению .
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Аем Вопля, Вы писали:
АВ>Я не прав? Если я не прав, зачем тогда ввели ключевое слово using в C#, а? Если и так все «автоматическое»?
using нужен чтобы освобождение ресурсов было детерминированным, в C++ вызов деструкторов детерминирован, а в .NET аналогичный функционал — финализаторы вызывается недетеримровано.
На using встречается не так часто, а основной ресурс, которым требуется управлять в unmanaged среде — память, не требует детерминированного освобождения.
Здравствуйте, CreatorCray, Вы писали:
CC>Вот мне всегда было непонятно, почему в плюс языка всегда пытаются отнести большую стандартную библиотеку? CC>Это конечно плюс, но не самого языка.
А сам язык без библиотек, это ничто, каким бы он ни был крутым, красивым, стройным (ни к одному из них я С++ не отношу ).
Lisp is not dead. It’s just the URL that has changed: http://clojure.org
AndrewVK пишет:
> Речь была не о том, что С++ говно, а о том, что хорошая платформа с > языком очень даже связана.
Кому на C++ нужен этот ABI ?
А С++, извините, был уже, когда вашей Java любимой и в зародыше
не было. И не было бы C++, не было бы и Java, потому как Java
прежде всего им и вдохновлена была.
С++ -- язык другой, и другого времени, того, когда на машине
было 640 килобайт памяти. Так что уж простите старику его
маленькие слабости.
Пацак пишет:
> Пардон, то есть ты хочешь сказать, что RuntimeException в java ждут > всегда? *Вот это* на самом деле новость-то.
Я имею в виду, что оно всегда может возникнуть. И если ты к нему не
готов, то это уже твоя проблемы.
Здравствуйте, MasterZiv, Вы писали:
MZ>А С++, извините, был уже, когда вашей Java любимой и в зародыше MZ>не было. И не было бы C++, не было бы и Java, потому как Java MZ>прежде всего им и вдохновлена была.
Так можно и до ALGOL-а дойти по индукции, впрочем, возраст языка не относится напрямую к его достоинствам.
MZ>С++ -- язык другой, и другого времени, того, когда на машине
было 640 килобайт памяти.
В то время, да и сейчас, C преобладает над C++, особенно на девайсах с малой памятью.
D>Распространённое заблуждение. В деструкторе C++ можно разместить процедуры освобождения только для элементарных ресурсов. Прежде всего "чистых" объектов в памяти. Любой ресурс с нетривиальной логикой освобождения, например, распределённая транзакция, и облом-с. Бо из деструктора нельзя нормальным образом передать информацию о возникновении ошибочной ситуации в процессе этого самого освобождения.
Философия С++ заключается в том, чтобы избегать создания объектов с одной лишь нетривиальной логикой удаления. Можно допустить утверждение: у любой разработанной самостоятельной сущности должно быть предусмотрено одно аварийное удаление, корректно работающее и не кидающее исключений. Иначе сущность считается опасной и должна быть завернута в что-то безопасное. Можно делать сколько угодно дополнительных нетривиальных "удалений", никто же не запрещает:
class CSuperResource
{
public:
void SuperMegaSyncStop(ISuperStopHelper * p);
void SuperMegaAsyncStop(some_ref_ptr<IStopObserver> pObserver);
void StopAnyway();
~CSuperResource()
{
StopAnyway(); // но должно быть одно аварийное, иначе придется ~CSuperResource переносить в private
}
};
Наличие одних лишь "нетривиальных удалений" — не только моветон, но и признак серьезных архитектурных ошибок.
Вот вам простая философская аналогия из мира системного программирования: допустим, вы написали свой аналог TrueCrypt'a, утилиту, которой можно управлять виртуальными шифрованными дисками. Виртуальный диск — это же сложный ресурс? Представим теперь гипотетическую ситуацию, что какой нибудь пользователь сделает mount некоторого виртуального диска с помощью вашей программы, поработает с ним, а unmount сделать не сможет из-за ошибки "нет памяти". Что это значит? Значит программа написана крайне плохо — вы должны были предусмотреть выделение критических необходимых ресурсов при mount'е, а если их нет, отказывать в mount операции, а не в unmount.
D>Кстати, ifstream из Вашего примера, тоже образец нетривиального ресурса. Бо закрытие файла может вызывать ошибочные ситуации. И чтобы их увидеть, потребуется явный вызов rdbuf()->close()
Строго говоря, не может. Ошибка при закрытии хендла означает только одно — его уже закрыли до вас. А "его уже закрыли до вас" в переводе на язык С++, означает "Случилось UB, программа написана некорректно, лучшее что можно сделать, это упасть и собрать дамп".
Здравствуйте, MasterZiv, Вы писали:
MZ>Кому на C++ нужен этот ABI ?
Тем, кто пишет фреймворки.
MZ>А С++, извините, был уже, когда вашей Java любимой и в зародыше MZ>не было.
Джава, она не моя и даже не любимая.
MZ> И не было бы C++, не было бы и Java
Это что то меняет?
MZ>С++ -- язык другой, и другого времени, того, когда на машине MZ>было 640 килобайт памяти. Так что уж простите старику его MZ>маленькие слабости.
Мы еще технические вопросы обсуждаем или тебе пофлеймить охота?
... << RSDN@Home 1.2.0 alpha 4 rev. 1137 on Windows Vista 6.0.6001.65536>>
Здравствуйте, MasterZiv, Вы писали:
>> Пардон, то есть ты хочешь сказать, что RuntimeException в java ждут >> всегда? MZ>Я имею в виду, что оно всегда может возникнуть. И если ты к нему не MZ>готов, то это уже твоя проблемы.
Готов или не готов к нему ты — это вопрос отдельный и вообще говоря философский. А готовность к нему программы в терминах языка выражается в конструкции try ... catch. И практика показывает, что в >90% методов в java RuntimeException никак не ловят и не ждут. Ибо все заранее ожидаемые косяки явно задекларированы через checked-исключения, а отлавливать вариант "случилось ХЗ чего" особого смысла не имеет. Из этого правила лично мне известны только два исключения — вышеописанная обертка вокруг checked при переопределении метода (что само по себе чревато потенциальными граблями) и вывод матершины в лог.
Здравствуйте, Ligen, Вы писали:
L>Философия С++ заключается в том, чтобы избегать создания объектов с одной лишь нетривиальной логикой удаления. Можно допустить утверждение: у любой разработанной самостоятельной сущности должно быть предусмотрено одно аварийное удаление, корректно работающее и не кидающее исключений.
У Вас каша в голове. Речь не об объектах, а о ресурсах, работа с которыми завёрнута в объект класса построенного согласно RAII (точнее, RAII в понимании оппонента). И не об удалении, а об освобождении этих самых ресурсов, путём автоматического вызова деструктора для объекта-обёртки размещённого на стеке.
Корректность же освобождения ресурса, нетривиальности логики этого самого освобождения вообще ортогональна, и никаким образом с ней не связана.
Ещё раз повторяю пример: распределённая транзакция. Здесь, при освобождении, нам необходимо получать/освобождать другие новые ресурсы, и иметь возможность адекватно реагировать на ошибочные ситуации, которые могут возникнуть при этих операциях. На автоматических вызовах деструкторов стековых объектов сделать это нормальным образом невозможно.
L>Наличие одних лишь "нетривиальных удалений" — не только моветон, но и признак серьезных архитектурных ошибок.
См. выше. Вы путаете тёплое с мягким.
L>Вот вам простая философская аналогия из мира системного программирования: допустим, вы написали свой аналог TrueCrypt'a,
Какой TrueCrypt в час ночи ??? Обычному приложению все эти critical'ы нафиг не нужны. Кончилась память ? Ну так идите лесом, или в магазин за DIMM'ами...
*Вы бы ещё ПО для управления ядерным реактором приплели...
D>>Кстати, ifstream из Вашего примера, тоже образец нетривиального ресурса. Бо закрытие файла может вызывать ошибочные ситуации. И чтобы их увидеть, потребуется явный вызов rdbuf()->close()
L>Строго говоря, не может. Ошибка при закрытии хендла означает только одно — его уже закрыли до вас.
Неправда. О конкретных ошибках возможных в этих моментах стандарты ничего не говорят. Постулируется только сама возможность отказа, с возвратом соответствующего значения из close()/fclose()
Если на Вашей конкретной платформе наблюдается описанное Вами поведение, то это проблемы исключительно Вашей конкретной платформы. Стандарт же допускает гораздо больше вариантов реализации.
L>Случилось UB, программа написана некорректно, лучшее что можно сделать, это упасть и собрать дамп
И это тоже чушь. С точки зрения C++, никакого UB здесь быть не может. Бо стандарт допускает и отказы, и многократный вызов close()
Пацак пишет:
> Готов или не готов к нему *ты* — это вопрос отдельный и вообще говоря > философский. А готовность к нему *программы* в терминах языка выражается > в конструкции try ... catch. И практика показывает, что в >90% методов в > java RuntimeException никак не ловят и не ждут. Ибо все заранее > ожидаемые косяки явно задекларированы через checked-исключения, а
java.lang
Class RuntimeException
java.lang.Object
extended by java.lang.Throwable
extended by java.lang.Exception
extended by java.lang.RuntimeException
Вы не ловите в ваших программах java.lang.Exception ?
> отлавливать вариант "случилось ХЗ чего" особого смысла не имеет. Из > этого правила лично мне известны только два исключения — вышеописанная > обертка вокруг checked при переопределении метода (что само по себе > чревато потенциальными граблями) и вывод матершины в лог.
Любой APP -сервер, думаю, обязан оборачивать выполнения
всех запросов в try...catch. CORBA ORB например (штатный от SUN)
это делает. Думаю, это же делают всякие JBoss etc.
Здравствуйте, MasterZiv, Вы писали:
MZ>java.lang MZ>Class RuntimeException MZ>java.lang.Object MZ> extended by java.lang.Throwable MZ> extended by java.lang.Exception MZ> extended by java.lang.RuntimeException MZ>Вы не ловите в ваших программах java.lang.Exception ?
Не туда копаете. Заложенная логика в отнесение исключения к проверяемым или непроверяемым исключениям никак не связана с приведенной вами иерархии наследования. К примеру, Exception является проверяемым, а вот RuntimeException — непроверяемым, несмотря на то, что является наследником Exception. С другой стороны, java.lang.Error, который также, как и java.lang.Exception, наследуется от java.lang.Throwable, не является проверяемым. Итого, с этой точки зрения никакой четкой логики нет. Здесь заложена логика на заложенной в данные исключения семантике, их 3 группы:
Наследники java.lang.Exception (но не наследники java.lang.RuntimeException!) — проверяемые.
Наследники java.lang.RuntimeException — непроверяемые. Семантика: ошибки программы, которые не должны возникать при правильном кодировании — нет смысла их программно обрабатывать (!), их надо ловить (регистрировать срабатывание) модульными тестами и на лету исправлять. К примеру, это выход за границы массива, деление на ноль и прочее.
Наследники java.lang.Error — непроверямые. Семантика: фатальная ситуация, которую практически невозможно устранить программным способом, хотя формально можно. К примеру, это переполнение стека, нехватка памяти и прочее.
Собственно, Пацак правильно пишет: паталогия всегда есть — но по заложенной логике нет никакого смысла обрабатывать непроверяемые исключения.
Здравствуйте, rsn81, Вы писали:
R>Наследники java.lang.RuntimeException — непроверяемые. Семантика: ошибки программы, которые не должны возникать при правильном кодировании — нет смысла их программно обрабатывать (!)
Неуверен, что все наследники RuntimeException подходят под Вашу классификацию. Вот SecurityException, например ?