C>Александреску написал книгу про С++. А вот президент Путин ничего не говорит про С++, а сколько он всего сделал!
Я бы не стал сравнивать Линуса и Путина. Линус, в отличие от Путина, сделал реально большое и приносящее пользу дело.
А книга по Си++... вы знаете, что сказал халиф про книги и Коран, сжигая библиотеку в Александрии? так вот, Коран в области Си++ — это книги Страуструпа, иногда на пару с Эллис. Дальнейшее, я думаю, понятно
Здравствуйте, Аноним, Вы писали:
MSS>>>Что сделал толкового Александреску и что сделал Линус? C>>Александреску написал книгу про С++. А вот президент Путин ничего не говорит про С++, а сколько он всего сделал! А>Да-да-да! Лучше бы он эту книгу не писал которую куча м...ов "прочитала", нихрена не поняла и давай писать программы в подобном стиле что поубивать хочется.
Нет силы разрушительной страшнее,
Чем кода стиль "Я-Прочитал-Александреску"...
It's kind of fun to do the impossible (Walt Disney)
Здравствуйте, Cyberax, Вы писали:
C>Здравствуйте, Maxim S. Shatskih, Вы писали:
MSS>>http://article.gmane.org/gmane.comp.version-control.git/57918 MSS>>...а я давно говорил нечто подобное, хотя и мягче, чем Линус. C>1) Баян. C>2) У Линуса мозг потек от ядерного программирования.
Brainleak ?
А вот в С++ деструктор бы собрал весь мусор.
Здравствуйте, Аноним, Вы писали:
MSS>>>Что сделал толкового Александреску и что сделал Линус? C>>Александреску написал книгу про С++. А вот президент Путин ничего не говорит про С++, а сколько он всего сделал! А>Да-да-да! Лучше бы он эту книгу не писал которую куча м...ов "прочитала", нихрена не поняла и давай писать программы в подобном стиле что поубивать хочется.
Не волнуйся, без этой книги эти нехорошие люди писали бы точно так же плохо — но в обычном old C++-стиле
Это просто раздувание еще одной священной войны. Что касается критики С++ то язык не без грехов, но во-первых часть этих грехов была унаследована от горячо любимого Линусом С, а во-вторых реально лучших альтернатив нет. Прежде чем ругать С++, предложите лучшую альтернативу и если она действительно будет так хороша люди на нее перейдут. Еще могу добавить, что подовляющее большинство критиков С++ его банально плохо знают и не понимают почему он устроен так сложно, т.е. критика С++ сводиться к тому, что язык слишком сложен, я его не понимаю и не понимаю код, который пишут другие — поэтому С++ плох. Плохой код можно писать на любом языке, так же как и хороший.
C>В Линуксе, например, бинарной совместимости вообще нет. И что? А вообще, лучше всего для бинарной совместимости на С++ использовать систему типа COM-интерфейсов.
Это и есть описанное Линусом подмножество Си++. У микрософта в PortCls оно используется.
C>Не согласен. Например, мне непонятен запрет template'ов — они реально помогают увеличить быстродействие без особого оверхеда. STL — это, по сути, библиотека контейнеров, и они все равно нужны. В том же Линуксе, контейнеры делаются с помощью макросов (т.е. творчество на тему "темплейты своими руками").
Темплейты — не самое худшее в Си++, хотя и их проабъюзить можно. Это как раз полезная фича языка.
Ссылки и operator+ всякие, и особенно operator T — процентов на 90 есть абъюз. Толковых мест, где ими можно пользоваться, раз, два, и обчелся — только библиотеки строк и контейнеров.
Не по делу примененный overloading — отвратительно. Даже cout << нечто — и то отвратительно. operator T отвратителен вдвойне — для него даже закорючки в синтаксисе не надо.
Ссылки нужны на деле только для того, чтобы поддержать operator++, operator[] и прочее, где операнд или результат есть lvalue. Соответственно, ссылки вне параметров и возвращаемых значений — просто ненужная фича, и причем дурацкая, ибо неполноценно дублирует указатели. Неполноценно потому, что не бывает указателей на ссылки и массивов ссылок.
Ссылки в параметрах и возвращаемых значениях оправданы только в operator XX, в обычной функции пойнтер лучше — в вызовах явно пишется &, что подсказывает, что параметр меняется в результате вызова. Запись f(a), от которой а изменилось, да еще и у f имя по-дурацки выбрано — мерзость.
Здравствуйте, ArtDenis, Вы писали:
AA>>Нет силы разрушительной страшнее, AA>>Чем кода стиль "Я-Прочитал-Александреску"...
AD>После прочтения александреску у меня не появилось желания писать в таком-же стиле, хотя возможность была
Значит ты уже зрелый профессионал. А вот на не окрепшие умы эта книга действует разрушительно
"For every complex problem, there is a solution that is simple, neat,
and wrong."
MSS>>Что сделал толкового Александреску и что сделал Линус? C>Александреску написал книгу про С++. А вот президент Путин ничего не говорит про С++, а сколько он всего сделал!
Да-да-да! Лучше бы он эту книгу не писал которую куча м...ов "прочитала", нихрена не поняла и давай писать программы в подобном стиле что поубивать хочется.
Здравствуйте, The Lex, Вы писали:
MSS>>Что сделал толкового Александреску и что сделал Линус?
TL>Первый написал много толковых книг по вопросу практики примения одного из самых распространенных языков программирования современности. Что такого "архивеликого" сделал второй? Почему рядом с Линусом не поставить, например, Билла Гейтса? Кто из двух последних "вообще круче"?
Александреску не просто еретик, а еретик, активно несущий свою ересь в массы, путем писания книг. Ясно, что писатели попадают в какой-то более крутой круг ада, чем простые содомиты и прелюбодеи
Ставить Торвальдса рядом с Гейтсом бессмыссленно. Первый — менеджер софтверного проекта, архитектор и кодировщик. Второй — успешный бизнесмен. Гейтс вполне мог бы заниматься и не софтварием, Линус — вряд ли.
А что там собственно такого умного написано? Первые 2 абзаца — "мы используем С, а не С++, шоб всякие ламеры не лезли". Вполне логично. Доля ламеров среди пишущих на С++ по прежнему превышает долю ламеров среди пишущих на С.
Абзац 3:
"C++ leads to really really bad design choices". — усе так и есть. C не позволяет схалтурить, объем исходников на С получается больше, поэтому горячим парням приходится сначала подумать а уж потом кодить С плюсами же можно по-быстрому налабать прототипчик и потом постепенно его дотачивать.
"You invariably start using the "nice" library features of the language like STL and Boost and other total and utter crap" — тут логика отсутствует. Не хочешь — не используй.
"infinite amounts of pain when they don't work" — ну это при использовании чужих библиотек завсегда бывает. Что характерно, если что-то don't work в своей библиотеке — amounts of pain из-за этого гораздо меньше (правда, работы больше). Но это, на мой взгляд, language-neutral feature. Лично меня приколы OpenSSL достали видимо ничуть не меньше, чем Линуса STL. Вот уж где
"(and anybody who tells me that STL and especially Boost are stable and portable is just so full of BS that it's not even funny)" — а кто с этим не согласен, тот какашка Оч содержательная и убедительная аргументация.
"inefficient abstracted programming models where two years down the road you notice that some abstraction wasn't very efficient, but now all your code depends on all the nice object models around it, and you cannot fix it without rewriting your app." Ну собственно это надо быть очень меедленным программистом (проще говоря, тупым тормозом), чтобы пару лет не замечать, что чего-то там круто тормозит.
Итого — С++ развращает программиста, поскольку для него есть слишком много библиотек, а в языке слишком много фич.
"In other words, the only way to do good, efficient, and system-level and portable C++ ends up to limit yourself to all the things that are basically available in C." Ну это просто брехня. В C++ по крайней мере проверки типов построже и переменные непосредственно перед использованием объявлять можно. Насчет portable — я сильно удивлюсь, если GIT или тем более linux kernel вдруг скомпиляется чем-то отличным от gcc.
"And limiting your project to C means that people don't screw that up, and also means that you get a lot of programmers that
do actually understand low-level issues and don't screw things up with any idiotic "object model" crap." — все так и есть, если убрать слова про "idiotic "object model" crap", которую, к слову, крутой Линус и реализует (на С, естественно). Потому что без "object model" именно crap и получится, хоть на С, хоть на С++, хоть на ассемблере.
"So I'm sorry, but for something like git, where efficiency was a primary objective, the "advantages" of C++ is just a huge mistake." — ну собственно вольному воля. Аргументация, правда, по-прежнему отсутствует.
"The fact that we also piss off people who cannot see that is just a big additional advantage." — а все остальные идет нафиг
Ну а дальше он собственно Monotone ругает — не знаю, может она и правда "horrible and unmaintainable mess", но чето в этом сомневаюсь. Она, по крайней мере, почему-то Cygwin для запуска под виндой не требует — в отличие от "portable" GIT. Т.е., "horrible and unmaintainable mess" на винду портировали, а portable и mantainable — нифига.
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, Alxndr, Вы писали:
AJD>>Значит ты уже зрелый профессионал. А вот на не окрепшие умы эта книга действует разрушительно
A>А что в ней такого разрушительного?
Эйфория от ощущения, что всё можно сделать в compile-time constraints плюс неумение чисто писать/читать шаблоны. В результате получается код, который
1) не работает
2) проще переписать, чем исправить
Про расширяемость, масштабируемость и прочие best practices уже и речи не идет.
Здравствуйте, Maxim S. Shatskih, Вы писали:
E>>А здесь http://video.google.com/videoplay?docid=6520647478274589397 Андрей Александреску мягко объяснил, что Линус смотрит на C++ со своей очень своеобразной колокольни. MSS>Что сделал толкового Александреску и что сделал Линус?
Александреску написал книгу про С++. А вот президент Путин ничего не говорит про С++, а сколько он всего сделал!
Помню, как-то один из создателей UNIX (Ричи, кажется). Сказал, что с архетикрутной точки зрения Linux -полный ноль.
А мораль, примерно такова: у кого-нибудь есть заблуждение, что Торвальдс является специалистом в области теории языков и С++ в частности?
Давайте еще, приведм слова моей соседки тети Даши о Java. Ибо она много сделала — вырастила двух дочерей. А не создала ядро какой-то там ОС, которая собрала вокруг себя целую тучу неофитов-фанатиков.
Здравствуйте, dupamid, Вы писали:
D>Плохой код можно писать на любом языке, так же как и хороший.
Не споря по существу, не могу не заметить, что на BF таки трудно...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
TL>Тут я не понял "за" или "против" этот аргумент и "за или против" чего. Тут вот совсем недавно и совсем рядом девушка хотела аналог std::string, но чтобы работал на ANSI C. В результате имеет "те же яйца, только сбоку" (к)
Здравствуйте, AntiFreeze, Вы писали:
AF>Слишком обобщенные решения для обычного прикладного программирования.
Это где же Александреску говорил, что его решения — для прикладного программирования???
А если какие-то идиоты принимаются писать прикладной код в стиле библиотечного кода, а гуй — на асме, а драйвер — на вижуал-бейсике — так это их персональные половые проблемы.
Pzz>Это плохая оптимизация — у нее слишком много тонких эффектов. Если что-то не может быть сделано прозрачно (а дешевая передача объектов в языке типа Си/C++ не может быть сделана прозрачно, в силу очень открытого интерфейса к реальной памяти машины), то лучше не делать этого вовсе.
Как хорошо, что Си не дает передавать структуры by value... и временных объектов не плодит...
Здравствуйте, Cyberax, Вы писали:
C>Нет. Ссылки, особенно константные ссылки, — это способ самодокументации кода. Если метод принимает константную ссылку — вызывающий может быть уверен, что метод не будет менять объект по этой ссылке (в разумном коде, естественно).
Константные ссылки в этом плане ничем не лучше константных указателей.
При этом если я в Си передаю чего-нибудь по значению, это видно сразу в точке вызова. А в C++ надо посмотреть еще на прототип функции, чтобы узнать, не берет ли она от объекта ссылку вместо значения.
Заметим также, что есть вещи, связанные с сылками, которые вообще остаются невидимыми. Например, функция, получившая адрес объекта, может за какой-нибудь надобностью его засейвить на будущее, что накладывает на меня обязательства не освобождать память, занятую этим объектом. В этом смысле, передача константной ссылки семантически очень отличается от передачи объекта по значению. Столь глубокое семантическое различие на мой взгляд заслуживает различия и в синтаксисе, причем в том месте, где объект передается, а не в том, где его принимают.
Здравствуйте, The Lex, Вы писали:
TL>Объективные аргументы в обоснование имеются? Не для спора — интереса ради: конструктивную критику всегда приветствовал лично я.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
E>>А разве сейчас обсуждаются результаты трудов Торвальда и Александреску? Имхо, обсуждаются сказанные ими вещи. И Александреску правильно говорит, что у Торвальдса команда из сотен очень таланливых разработчиков, они занимаются достаточно специфическими задачами, у них нет жестко оговоренных сроков и бюджетов. В таких условиях C может быть отличным языком. Тем не менее вокруг полно задач, для которых есть сроки, бюджеты и гораздо меньшие команды. В таких условиях C вряд ли много лучше C++, скорее наоборот.
Pzz>Насчет сроков и бюджетов, это немножко подленькая точка зрения. Она как бы намекает на то, что ядерные разработчики работают медленнее и неэффективнее, чем индустриальные, из-за того, что они могут себе это позволить. Но на самом деле, всем бы работать с такой производительностью, с какой работают разработчики ядра линиха.
Я добавлю — в ядре виндов тоже практически нет Си++, и как-то они не горят желанием его туда тянуть. А аргументы Александреску против Линуса (что это опенсорс, никем толком не руководимый) к ядру виндов не относятся.
Здравствуйте, eao197, Вы писали:
E>А разве сейчас обсуждаются результаты трудов Торвальда и Александреску? Имхо, обсуждаются сказанные ими вещи. И Александреску правильно говорит, что у Торвальдса команда из сотен очень таланливых разработчиков, они занимаются достаточно специфическими задачами, у них нет жестко оговоренных сроков и бюджетов. В таких условиях C может быть отличным языком. Тем не менее вокруг полно задач, для которых есть сроки, бюджеты и гораздо меньшие команды. В таких условиях C вряд ли много лучше C++, скорее наоборот.
Насчет сроков и бюджетов, это немножко подленькая точка зрения. Она как бы намекает на то, что ядерные разработчики работают медленнее и неэффективнее, чем индустриальные, из-за того, что они могут себе это позволить. Но на самом деле, всем бы работать с такой производительностью, с какой работают разработчики ядра линиха.
Здравствуйте, lazyden, Вы писали:
C>> В текущей Mac OS X в ядре тоже используется С++. L>Да, IOKit это с++, точнее говоря embedded c++, который по сути дела си-с-классами с кучей ограничений — стл, бустом и темплейтами там не пахнет. L>Отдельная песня — это описание класса который позволяет изменения (добавление новых полей и виртуальных методов), при этом бинарно совместим L>с предыдущей версией этого класса.
В Линуксе, например, бинарной совместимости вообще нет. И что? А вообще, лучше всего для бинарной совместимости на С++ использовать систему типа COM-интерфейсов.
L>
L>In other words, the only way to do good, efficient, and system-level and portable C++ ends up to limit yourself to all the things that are basically available in C.
Не согласен. Например, мне непонятен запрет template'ов — они реально помогают увеличить быстродействие без особого оверхеда. STL — это, по сути, библиотека контейнеров, и они все равно нужны. В том же Линуксе, контейнеры делаются с помощью макросов (т.е. творчество на тему "темплейты своими руками").
Здравствуйте, hexis, Вы писали:
H>Я думаю, что в целом Линус прав, но кое в чем он ошибается. Просто у H>этих языков — принципиально разные цели. Настолько разные, что их, по H>большому счету, не имеет особого смысла сравнивать. C++ (как и все ОО H>языки), в первую очередь, ориентирован на эффективность разработки и H>сопровождения программы, а C — на эффективность исполнения (память, H>скорость, объем кода).
Не согласен абсолютно. Одним из главных принципов при разработке С++ было: "you don't pay for what you don't use". Этот принцип вполне нормально соблюдается почти всеми реализациями С++. В результате, на С++ можно писать так же быстро (и даже быстрее — благодаря исключениями, например) как и на С. Более того, можно вообще писать точно так же как и на С (за исключением мелких различий в синтаксисе).
Проблема в том, что многие "C++-программисты" не знают нормально язык — в случае с чистым С они просто были бы недостаточно квалифицированы для разработки. Ну и получаются в итоге жуткие монстрики.
Здравствуйте, hexis, Вы писали:
H>Например, использование виртуальных функций в C++ — повсеместная H>практика. А в C — редкость.
В нормальном коде на С++ — они используются только для классов, которые реально могут быть полиморфными.
H>Использование таблиц виртуальных функций в C я не разу не встречал.
В С — это повседневная практика. Для GTK смотри GObject, для Линукса — тот же интерфейс модулей или VFS и т.п.
H>Активное использование шаблонов в некоторых случаях улучшает H>производительность, и, как правило, приводит к увеличению объема кода.
Объем кода — это фигня, в разумных пределах.
H>
class A
H>{
H>public:
H> A();
H> ~A();
H>};
H>void funcb(A *);
H>void func()
H>{
H> A a;
H> funcb(&a);
H>}
Для табличной обработки исключений — цена будет равна нулю на путях, которые не бросают исключения. Благодаря этому, программы, которые используют исключения для обозначения ошибок, могут работать быстрее программ с тупой проверкой кодов возврата. Не веришь?
H>Насколько я понимаю, Линус говорит о том, что C делает эту цену H>явной — программисту придется самостоятельно написать весь этот код.
Угу, именно в этом и проблемы. Каждый раз тупо писать кучу кода.
Добавлю от себя — ссылка закрывает арифметику указателей. Что возлагает на компилятор контроль за тем что я могу случайно (при синтаксисе С/C++ это как два байта переслать) сделать инкремент указателя (а хотел — обьекта). Оччень приятная мелочь.
Здравствуйте, OCTAGRAM, Вы писали:
OCT>Cyberax пишет:
>> Ты знаешь, я как-то привык доверять *моим* ощущениям в тех областях, где >> я компетентен.
OCT>А, ну да. Если Ада похожа на Оберон, то Ада — это явно не та область, OCT>где компетентен. Логично. Ну тут всё же было мнение человека, OCT>действительно знающего Аду.
with Ada.Text_IO;
procedure Hello is
begin
Ada.Text_IO.Put_Line("Hello, world!");
end Hello;
Я вот совсем не знаю Аду, но когда я вижу в коде begin/end моя рука сама тянется к пистолету.
Здравствуйте, <Аноним>, Вы писали:
MSS>>>Что сделал толкового Александреску и что сделал Линус? C>>Александреску написал книгу про С++. А вот президент Путин ничего не говорит про С++, а сколько он всего сделал! А>Да-да-да! Лучше бы он эту книгу не писал которую куча м...ов "прочитала", нихрена не поняла и давай писать программы в подобном стиле что поубивать хочется.
а Вы бы не могли написать, что конкретно Вас не устраивает?
а то как-то очень уж голословно у Вас получается...
Здравствуйте, Maxim S. Shatskih, Вы писали:
MSS>Я добавлю — в ядре виндов тоже практически нет Си++, и как-то они не горят желанием его туда тянуть. А аргументы Александреску против Линуса (что это опенсорс, никем толком не руководимый) к ядру виндов не относятся.
Ну почему же? Вполне есть — многие драйвера его успешно используют.
Здравствуйте, Maxim S. Shatskih, Вы писали:
MSS>>>Я добавлю — в ядре виндов тоже практически нет Си++, и как-то они не горят желанием его туда тянуть. А аргументы Александреску против Линуса (что это опенсорс, никем толком не руководимый) к ядру виндов не относятся. C>>Ну почему же? Вполне есть — многие драйвера его успешно используют. MSS>До появления KDMF из микрософтного — только PortCls, FtDisk и 2мерный графический движок.
Я имею в виду third-party драйвера.
MSS>Си++ных АПИ в ядре нет и сейчас, даже с KMDF. KMDF и GRE обернуты в Сишный АПИ. Собственно, GREшный CLIPOBJ_bEnum — да, это CLIPOBJ::bEnum.
А C++ные API и не нужны. Я бы даже сказал, что они вредные из-за зависимости от версии компилятора. Пока что, лучше всего подходят API в С-шном стиле или COM-объекты.
Здравствуйте, Cyberax, Вы писали:
Pzz>>Константные ссылки в этом плане ничем не лучше константных указателей. C>Лучше. Константные ссылки — это по сути оптимизация передачи по значению.
Это плохая оптимизация — у нее слишком много тонких эффектов. Если что-то не может быть сделано прозрачно (а дешевая передача объектов в языке типа Си/C++ не может быть сделана прозрачно, в силу очень открытого интерфейса к реальной памяти машины), то лучше не делать этого вовсе.
C>Язык нам дает гарантию, что если мы не будем делать идиотских поступков — то у нас не будет проблем.
При этом грань, отделяющая идиотский поступок от неидиотского столь тонка...
Здравствуйте, Maxim S. Shatskih, Вы писали:
MSS>Темплейты — не самое худшее в Си++, хотя и их проабъюзить можно. Это как раз полезная фича языка.
MSS>Ссылки и operator+ всякие, и особенно operator T — процентов на 90 есть абъюз. Толковых мест, где ими можно пользоваться, раз, два, и обчелся — только библиотеки строк и контейнеров.
MSS>Не по делу примененный overloading — отвратительно. Даже cout << нечто — и то отвратительно. operator T отвратителен вдвойне — для него даже закорючки в синтаксисе не надо.
Как человек, которому на C++ довелось посчитать математику (в том числе и с матрицами комплексных чисел в 99-2000-й годах) и сделать несколько систем сериализации/десериализации данных могу сказать вам "Фи!" за подобные рассуждения.
Если вам не нужны ссылки и перегрузка операторов при разработке драйверов -- не пользуйтесь. Оставте их тем, кто как я успешно применяет эти фичи языка в user-space.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Pzz, Вы писали:
Pzz>Потом, constantness в C++ — понятие вообще довольно "плюшевое". В силу того, что C++ унаследовал от Си понятие о значении объекта, как о содержимом тех байтов памяти, из который состоит объект.
Прямо скажем, это просто порочная практика "любителей копаться там, где никому больше не нужно": почему-то любимый вопрос на собеседовании "как по-вашему представлен экзепляр класса бинарно?" — на практике полезности не вызывает.
То, что _можно_ посмотреть на все двоичные внутренности объекта "плюсов" вовсе не означает что так _нужно_ делать.
Pzz>К примеру, взять такой объект: Pzz>
Pzz>struct str
Pzz>{
Pzz> char *s;
Pzz>};
Pzz>
Pzz>В буквальном C++'ном понимании его константность заключается в том, что я не смогу поменать указатель s. Но мне ничего не помешает пописать в память, на которую ссылается этот указатель. Изменится при этом значение объекта или нет? Формально — нет, ведь объект лишь содержит указатель, а он не поменялся. Однако если я в силу своего высокоуровнего абстрактного понимания считаю значением объекта именно содержание строки, на которую он ссылается, значение очевидно поменялось. При этом у меня нет синтаксического способа объяснить компилятору эту тонкую семантическую грань — разве что в комментарии написать, и надеяться, что кто-то (не компилятор!) его прочтет.
Уел!!!
Ну ладно: как ты то же самое ограничишь в Си? А никак.
В тех же "плюсах" это может ограничить даже школьник, перебросив член в защищенную область и нарисовав публичные аксессоры.
Применить к C++ явно "сишный" подход и поставить факт в укор "плюсам" —
Здравствуйте, The Lex, Вы писали:
Pzz>>Этот аргумент утверждает следующее: если Вы не хотите, чтобы в Вашем проекте появился STL, не используйте язык, на котором STL можно написать. Ничего другого не сработает.
TL>Да? Извините, но вы в каком-то странном окружении работает. Если в проекте есть правило "мы не используем stl" — то, конечно, должно быть хоть
Это Вы в каком-то странном окружении работаете
Мне приходится работать с такими людьми, которые есть. Которые, например, способны найти внутри исходника понравившуюся им static функцию, убрать слово static, вынести функцию наружу и начать применять. Забыв спросить меня, согласен ли я впредь поддерживать работоспособность этой функции.
В результате, когда я ее таки ломаю (а я не обещал ее не ломать — на то она и static), в говне оказываюсь я. Как же, у них все работало, пока не пришел злобный я, и все не сломал (т.е., не внес "багу" в "работающий" код).
Hint: такие люди называются продвинытые индусы (видимо благодаря им такой стиль разработки называется индустриальным. Их менее продвинутые собратья умудряются добиться подобного же эффекта, используя только public интерфейс — путем возложения неоправданных надежд на особенности поведения реализации интерфейса в данной конкретной версии. Эти, на самом деле, еще хуже — поскольку они не гадят в мой код, заметить их вредоносность можно, только время от времени просматривая их код. Что вредно для кармы.
Pzz>>Я не про это. Я про то, что в случае Си гораздо проще проследить код до того, что там происходит на самом деле. В C++ сделано очень многое, чтобы усложнить такой анализ.
TL>Угу. Вообще-то это не так — это раз. А если это так, то, имхо, вы "копаетесь в песке и рассматриваете цветные камешки", вместо того чтобы "строить шоссе на 8 полос". Может у вас такая специфика, но подавляющему большинству реальных проектов это просто не нужно.
Копаться в песке приходится, когда машинка не едет, по казалось бы, ровному 8-полосному шоссе. При индустриальном подходе к делу, такое случается сплошь и рядом.
TL>Кстати, низкоуровневый код — а точнее, HAL — таки и правда "ближе и проще" на "простом си". Вот только как только начинаются абстракции — как тут же самое время разделить слои и писать ниже нижнего на чем-то более подходящем, вместо того чтобы сперва реализовывать своими руками "что-то более подходящее", а потом уже "строить абстракции" на его базе. имхо.
Это, по-моему, заблуждение, путать код, который близок к железу и код, у которого простые абстракции. Сложность абстракций не зависит от близости к железу.
Собственно, что я хочу сказать, высокоуровневые вещи, конечно, лучше писать на высокоуровневом языке. Только C++ не из их числа (высокоуровневых языков).
Pzz>>Без явного каста такое присваивание выдает предупреждение. С явным кастом можно и в C++ присвоить.
TL>Только что проверил: например VC++ 7.1 выдает "error C2440: 'initializing' : cannot convert from 'int' to 'int *'" на следующую строку:
Здравствуйте, The Lex, Вы писали:
TL>>>Ключевой момент был неоднократно упомянут и указан явно тоже: практик в _чем_ именно? E>>В программировании довольно сложных систем. А Александреску практик в написании книжек...
TL>Я в Линусе чайник: что еще кроме линукса Линус написал?
Git и книжку про то, как ему было в кайф писать линух и как ему нравится кататься на красном BMW.
Но я бы считал его главной заслугой способность поддерживать разработку ядра линуха на плаву. Это нетривиальная задача, с точки зрения управления проектами.
Здравствуйте, hexis, Вы писали:
H>Я думаю, что в целом Линус прав, но кое в чем он ошибается. Просто у H>этих языков — принципиально разные цели. Настолько разные, что их, по H>большому счету, не имеет особого смысла сравнивать. C++ (как и все ОО H>языки), в первую очередь, ориентирован на эффективность разработки и H>сопровождения программы,
Это заблуждение. C++ в первую очередь рассчитан на индустриальный стиль программирования — когда главный индус описывает интерфейсы, а подчиненные индусы наращивают мясо на эти интерфейсы. Это не обеспечивает эффективности разработки, это обеспечивает массштабируемость (больше индусов — больше кода, почти в линейной пропорции, до тех пор, пока bandwidth главного индуса не исчерпан. А потом — кирдык).
Здравствуйте, Cyberax, Вы писали:
H>>Я же написал о другом — об объеме требуемого машинного кода. В H>>приведенном примере компилятор не знает, может ли funcb генерировать H>>исключения, поэтому обязан всегда обрабатывать исключения чтобы H>>корректно отработал деструктор. C>Нет. Тебе стоит узнать как работают исключения. Ладно, делаем тест:
Это ты привел пример того, как работает обработка исключений на Linux — там используется табличный подход. Для Windows 32-бита, будет сгенерирован код для прологи и эпилога функции и он будет отличаться того, который будет без исключений. Оба подхода имеют свои плюсы и минусы. Плюс табличного подхода ты привел — почти нет дополнительного сгенерированного кода. Минус — объем таблиц, когда областей видимости, временных объектов и т.п. объем таблиц может быть огромен. Так как каждое создание объекта и его уничтожение создает новый контекст обработки исключений. Подход с генераций кода более компактен, но всегда дает накладные расходы. Кроме того, наличие возможности исключений подавляет некоторые оптимизации компилятора (исключения создают дополнительные переходы к коде, например любая функция может не вернуться — бросить исключение), так что не весь эффект от исключений выражен в новом коде или таблицах.
J>>Это где же Александреску говорил, что его решения — для прикладного программирования??? J>>А если какие-то идиоты принимаются писать прикладной код в стиле библиотечного кода, а гуй — на асме, а драйвер — на вижуал-бейсике — так это их персональные половые проблемы.
E>Да и в "Моей Борьбе" ничего такого в целом ненаписано. Но идиоты нашлись и находятся до сих пор... Может таки не толкьо в идиотах дело?
Только в них. Сам по себе майн кампф не стал бы причиной концлагерей. Книга сама по себе не в состоянии изменить этот мир, она только одно из средств пропаганды и агитации.
IMHO, это искусственный мертворожденный язык Можешь почитать про сравнение С (или С++) и Паскаля многое верно и для Ады.
>> и если она действительно будет так хороша люди на нее перейдут. OCT>Наиииивный. В IT мире другие законы. Большинство равняется на OCT>большинство, создавая положительную обратную связь. Управляется это OCT>большинство в большей степени деньгами и маркетингом, нежели здравым OCT>смыслом. Любая нелепость может стать обыденностью. Об алгоритмах и OCT>программах <http://is.ifmo.ru/reflections/algorithms/> :
И что эта ссылка доказывает???
>> Еще могу добавить, что подавляющее большинство критиков С++ его >> банально плохо знают и не понимают почему он устроен так сложно, т.е. >> критика С++ сводиться к тому, что язык слишком сложен, я его не >> понимаю и не понимаю код, который пишут другие — поэтому С++ плох. >> Плохой код можно писать на любом языке, так же как и хороший. OCT>Да, но это не оправдание для тех остальных, кто C++ знает хорошо.
От тех, кто С++ хорошо знает, критика заключается в обсуждении проблем языка, как их избегать или как нужно (лучше) изменить язык (да, С++ меняется). К обсуждаемой "критике" С++, вышеперечисленное не относиться — это эмоции и не понимание.
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, jazzer, Вы писали:
J>>Ты не озвучишь его опыт ведения проектов на С++? J>>Он ведь именно о С++ изволит говорить, а я вот не помню, чтоб он вообще на С++ серьезно писал, не говоря уже о руководстве С++-проектами.
E>Он говорит о том, чем ему не нравится С++ применительно к большому и сложному софтверному проекту. Возможно, конечно, он С++ не знает, но ты-то может быть и знаешь. Так что можешь оценить его аргументацию. Только не в стиле "он дурак, и С++ не знает", а в стиле "вот чувак имеет такие-то опасения. Что я сделаю в своём С++ проекте, чтобы его опасения не стали правдой?"
Можно по пунктам?
А то те нападки, что я у него вижу, либо полная флеймовая ахинея после которой его вообще трудно уважать за что бы то ни было ("you are full of bullshit"), либо "общеменеджерские" и не зависят от языка (так я по этому поводу лучше Брукса почитаю или того же Gaperton-а, чем Линуса, у которого за плечами весьма специфический проект в смысле условий разработки и персонала и эти условия в моем проекте точно не повторятся), либо, когда он касается именно С++, показывают его полное незнание разработки на С++.
Чем тратить время на борьбу с его ветряными мельницами, я, честное слово, лучше почитаю тех, кто либо профессионал в менеджменте вообще, либо профессионал в разработке, проектировании и управлении проектами именно на С++ — потому что это будет то, что есть в реальности, а не то, что кому-то с его далекой колокольни кажется.
Pzz wrote: > > H>Ну, тогда мы явно заблуждаемся вместе. Что такое "индустриальный" > H>стиль программирования, как не эффективность на этапе разработки? > > Для начала надо определить понятие эффективности. Но как бы не была
Не претендуя на всеобъемлющее, абсолютно точное или каноническое
определение, я бы сказал так: эффективность, в широком смысле, — это
соответствие объема потребляемых ресурсов (или других параметров)
заданным (приемлемым в данных условиях). Под ресурсами (параметрами)
могут пониматься разные вещи — время разработки, качество разработки,
управляемость (расширяемость) кода, объем исходного текста, читаемость
(понимаемость) текста программистами определенного уровня, время
исполнения, объем машинного кода, объем памяти и т.д и т.п.
Решение эффективно, если позволяет оставаться в рамках заданных
параметров. Например требование масштабируемости и возможность
распараллеливания — это тоже один из критериев эффективности самого
процесса разработки.
> определена эффективность, ясно, что она является дробью, в числителе у > которой то, что мы преобрели, а в знаменателе — то, что потратили.
Да, согласен. Конечно, хотелось бы достичь лучших показателей по всем
параметрам одновременно. Но, на практике это возможно только для
программ класса "hello world". Уже в более-менее крупных проектах,
приходится балансировать, исходя из разных показателей. И критерии
эффективности по каждому параметру выбираются для каждого проекта.
Например, типичными требованиями являются: при первичной разработке
оптимизировать время разработки (быстрее получить продукт), при
вторичной — время исполнения (повысить качество реализации). Вообще,
вторичные реализации обычно дают существенно другую картину — и по
объемам исходного текста, и по качеству реализации, и по времени
исполнения. Все это — совершенно нормально и обычно говорит не о
качестве исполнителей в первой и второй команде, а о том, что в
результате первой реализации было получено более глубокое понимание
задачи (разработчиками и заказчиком) и изменились критерии эффективности.
D>Так что это очень индивидуально и зависит от того сколько объектов создатеся и разрушается, включая все локальный, временые переменные и временные переменные создающиеся под условием типа "some_cond ? A() : f(B())", здесь будет созадана или временная переменная типа A или B и в конце вычисления полного выражения так переменная которая была созданна должна быть разрешена. Такого рода вещи создают очень много EH контекстов.
EH контекстов (фреймов) такие вещи обычно не создают. EH фрейм обычно создаётся один на функцию. Все создания объектов с деструкторами (в т.ч. "some_cond ? A() : f(B())") просто инкрементируют неявный счётчик — некий аналог счётчика команд IP. По значению этого счётчика обработчик исключения (в т.ч. неявный, который генерируется компилятором и рушит объекты) может точно сказать какие объекты сейчас живы на стеке (т.е. какие надо разрушить).
Поэтому создания локальных объектов в функции зачастую приводят лишь к одной машинной инструкции add (когда неявный счётчик лежит в регистре).
В С коде так же зачастую поддерживается аналогичный счётчик, что бы можно было вынести код разрушения ресурсов в единое место. Однако в С коде этот счётчик так же зачастую совмещается с самими объектами. Например, значение 0 для указателя — это пример счётчика объектов, совмещённого с самим объектом. Но по сути это ничего не меняет, т.к. всё равно нужна одна дополнительная инструкция для инициализации этого указателя в 0 вначале функции.
Т.е. получается практически полностью аналогичный код. Только в С++ он создаётся неявно компилятором.
Здравствуйте, Сергей, Вы писали:
D>>Это ты привел пример того, как работает обработка исключений на Linux — там используется табличный подход. С>Думаю, это специфика компилятора, линукс здесь ни при чём.
Обычно устройство обработки исключений является частью ABI для того чтобы код скомпилированный разными компиляторами мог работать вместе. Посмотри например ABI System V i386 или ABI AMD64. В Linux ABI следуют достаточно строго. На Windows больше разнообразия, можно сказать, что MS фактически установила на нем свой ABI (не до конца документированный, в частности как раз обработка исключений не полностью документирована) поэтому на Windows больше разнообразия.
Здравствуйте, Left2, Вы писали:
L>Добавлю от себя — ссылка закрывает арифметику указателей. Что возлагает на компилятор контроль за тем что я могу случайно (при синтаксисе С/C++ это как два байта переслать) сделать инкремент указателя (а хотел — обьекта). Оччень приятная мелочь.
+1
И аналогично c присваиванием:
void f(int* p)
{
++p; // а хотели ++(*p)
p = 0; // а хотели (*p) = 0
}
void f(void** p)
{
void* l = p; // а хотели void* l = (*p)
}
Фактически получается, что передача объекта через указатель вводит второй, дополнительный объект — помимо самого значения, появляется ещё указатель на значение. В большинстве случаев этот дополнительный объект совершенно не нужен — т.е. мы не хотим производить с ним никаких действий, только использовать для обращения к самому значению. И при этом обращения к этим двум объектам записываются достаточно похоже. В случае с именем 'p' это ещё не так очевидно, а в случае с, например, contract_address и *contract_address ситуация становится значительно хуже, т.к. при чтении кода мозг фокусируется на семантике, т.е. елси я вижу contract_address, то я думаю о адресе контракта, не смотря на то, что это на самом деле накая деталь имплементации под названием указатель на адрес контракта.
Здравствуйте, Pzz, Вы писали:
E>>А разве сейчас обсуждаются результаты трудов Торвальда и Александреску? Имхо, обсуждаются сказанные ими вещи. И Александреску правильно говорит, что у Торвальдса команда из сотен очень таланливых разработчиков, они занимаются достаточно специфическими задачами, у них нет жестко оговоренных сроков и бюджетов. В таких условиях C может быть отличным языком. Тем не менее вокруг полно задач, для которых есть сроки, бюджеты и гораздо меньшие команды. В таких условиях C вряд ли много лучше C++, скорее наоборот.
Pzz>Насчет сроков и бюджетов, это немножко подленькая точка зрения.
"Немножко подленькая" -- это как "немножко беременная".
Pzz>Она как бы намекает на то, что ядерные разработчики работают медленнее и неэффективнее, чем индустриальные, из-за того, что они могут себе это позволить.
Она не намекает, она прямо говорит -- если ты сам Вася Пупкин и с тобой работает Федя Иванов, и срок сдачи вчера, и зарплата фиксированная, и заказчик мозги компостирует, и к проекту у тебя душа не лежит, то это совсем другая ситуация, чем когда ты вечерком в mailing-list обсуждаешь с Коксом и Торвальдсом детали очередного патча к очередной версии ядра которое еще не понятно когда зарелизят.
Pzz>Но на самом деле, всем бы работать с такой производительностью, с какой работают разработчики ядра линиха.
Вот и славно. Клепают ребята себе ядро Linux-а на C -- всем хорошо. Другие ребята на C++ KDE для этого ядра сделали. Кому от этого хуже стало?
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, The Lex, Вы писали:
Pzz>>Это плохая оптимизация — у нее слишком много тонких эффектов. Если что-то не может быть сделано прозрачно (а дешевая передача объектов в языке типа Си/C++ не может быть сделана прозрачно, в силу очень открытого интерфейса к реальной памяти машины), то лучше не делать этого вовсе.
TL>Имхо, это не "открытость интерфейса к реальной памяти" — это скорее "наследие адресной арифметики": по неновому уже стандарту первое попавшееся число указателю присвоить простым присваиванием нельзя. Имхо, совместимость в области адресной арифметики с ANSI C, включая некоторые ограничения — тоже одна из полезных фич, позволяющих в одном коде объединять и верхние уровни абстракции, и нижние — реализации.
Это наследие совместимости с Си. В Си такая открытость к аппаратуре была сделана вполне сознательно. В C++'е она мешает созданию нормальных высокоуровневых абстракций. В первую очередь потому, что трудно полностью скрыть тот факт, что управление памятью осталось ручным. И что любые объекты — всего лишь байты в памяти.
Если бы язык проектировался начисто, а не рос из Си, как само растется, вполне можно было бы от source level совместимости с Си отказаться, но предусмотреть способ взаимного procedure calls между языками. Тем более, что там от этой совместимости уже сейчас мало чего осталось.
Pzz>>При этом грань, отделяющая идиотский поступок от неидиотского столь тонка...
TL>В ANSI C она еще тоньше. имхо.
Си значительно проще и прозрачнее. Это большое достоинство.
> S>А никто и не предлагает интерфейсы плюсовые наружу выставлять... > > Т.е. вернулись к началу ветки — к плоским COM-подобным интерфейсам (по сути — таблица с указателями на функции).
Да меня собственно и сишный интерфейс вполне устраивает. Речь шла о том, что для реализации "потрохов" системы необязательно ограничиваться только С.
> Кроме того такое плоское апи уменьшает сцепление — оно не зависит даже от языка реализации интерфейса (это азы кома, вроде бы).
Это дает любое ABI, не обязательно COM. Вопрос только в реализуемости и сложности реализации данного ABI на других языках и разных трансляторах одного языка.
> С классическими монолитными ядрами вроде уже никто не работает — динамически подружаемые модули составляют существенную часть работающего ядра. Апи подсистем ядра для этих модулей должно быть плоское. Подсистемы ядра общаються между собой и тоже, в идеале, должны обладать плоским апи (вдруг мы захотим сменить ну, например, шедулятор ). Но темлейты не дают нам такой гибкости, точнее, темплейты завернутые в плоский апи теряют всю свою темплейтность.
Ну теряют, а в чем проблема то? Мы не можем из одного модуля выставить шаблон непонятно чего в другой модуль? А оно вообще надо? Зато для использования внутри своего модуля можно не кодировать каждый раз какой-нибудь хэшмэп и не пользоваться голимым void*.
> Попробуйте придумать/написать плоскую обертку для stl — получиться что-то вроде at&tшной сdt (с кучей указателей на функции и void * в качестве контейнерного элемента).
Ну и? Смысл этого действия в чем?
> Плоский апи — это границы применения темплейтов, также граница использования исключений, множественного наследование, rtti и прочих особенностей с++. Вроде бы сразу появляеться антипример — сильно-теплейтная АТЛ для плоского COM вполне существует и является вобщем state-of-art библиотекой. Но вот тут и возникает отличие — реализуя в коме свой IStream, вы одновременно реализуете свой ISequentialStream и свой IUnknown. Однако в ядре вы, реализуя свой IStream, должны использовать предоставленный системой ISequentialStream которой в свою очередь будет использовать предоставляемый системой IUnknown (это аналогия, не буквально).
Ну, а проблема-то в чем?
> Допустим я пишу свой драйвер для сетевого юсб-девайса. Я должен предоставить интерфейс outputPacket(const void * raw, size_t size), зарегить его в системе и получить от системы интерфейс для юсб. В методе я заполняю USBPacket и вызваю у юсб-интерфейса метод usbSendCommand(USBPacket somePacket). Все. Тут (в заполнении структуры USBCommand) негде разгуляться всем фичам с++.
Ну раз негде — не используй их, в чем проблема-то? А вот если этот USB-device представляет из себя убогий юсб винмодем, то там наверное еще кучу всякой фигни посчитать придется...
> Кратко: > 1) современное ядро ос не монолитно и представляет собой большое количество модулей, причем часть модулей подгружаеться/выгружаеться в рантайме.
да. Разумеется, писать на С++ монолитный софт гораздо приятнее. Однако и в случае жесткой разбивки на тонкие уровни С++ все равно удобнее С.
> 2) модули выполняют какую-то одну относительно несложную задачу.
одну — да, несложную — нет. Поскольку вряд ли можно считать несложной задачей рендеринг или ЦОС.
> 3) для выполнения каких-то запросов эти модули выстраиваются в стек и разные уровни стека между собой общаются на плоском апи.
да.
> В результате размеры и сложность этих модулей становятся небольшими, их внешние интерфесы — плоскими.
размеры и сложность — нет (все таки 5 миллионов строк кода, пусть и побитые на большое количество модулей), внешние интерфесы — да.
> А это ведет к тому что в ядре > 1) не подходит тот шаблонный подход к проектированию, который используеться для билиотек типа стл, атл, буста.
Фишка в том, что библиотеки и софт, который их использует, вообще проектируются (должны, по крайней мере) по-разному. Поэтому лично я считаю, что тут более уместно разделение библиотека/код, который ее использует, а ядро это или там гуи — дело десятое.
> 2) полноценный с++ оказываеться просто не нужен, и полное его использование приводит к овердизайну.
Полное использование — это "чтоб було"? Разумеется, так не надо делать.
> Хотя принципиально никто не мешает использовать туже стл в ядре. Но вобщем никто и не мешает написать само ядро на пэ-ха-пэ или луа, у них есть даже одно преимущество перед с++ — сборка мусора
Вот насчет gc в ядре у меня есть большие сомнения... Ну да посмотрим, что у MS с их сингулярити получится.
> S>В бусте то ли уже появились, то ли вот-вот будут. А пока широко распространенных нету — и самому недолго написать. > Я понял — известных реализаций типа queue.h нет. Ну на нет и суда нет, хотя отелось бы посмотреть как это будет выглядеть в темплейтах с++.
Известные реализации есть. Нет широко распространенных. Посмотреть, как оно выглядит на С++, можно здесь: http://svn.boost.org/trac/boost/browser/trunk/boost/intrusive
> S>Ситуация тут ровно та же, что и с макросами. И даже если все "руками написать", то — сюрприз — все равно две копии кода будут Так что в качестве аргумента против шаблонов — не катит. > тут не макросы vs шаблоны, а "шаблонный" подход к проектированию vs плоский комоподобный апи.
Что такое собственно "шаблонный подход к проектированию"? Такого термина я не встречал.
> А макросы против шаблонов почти всегда не катят — это очевидно.
Не всем
> S>С чего бы это система контроля версий вдруг стала system-level? > Требование к софту программеров и не_программеров разные (правда общий момент есть — чтобы работало и не глючило ). Поэтому ядро, службы/демоны, средства разработки — все то, что не решает проблемы пользователя-не_программиста я отношу к system-level. Возможно у меня сильно шырокое определение system-level , спорить не буду.
Да уж широковато, на мой взгляд.
> S>Лень мне по их исходникам лазить... А без изучения — какое может быть сравнение? Да и квалификацию писателей все равно не учтешь. > Да одинаковые у них квалификации,
Вообще-то квалификации ядрописателей линукса очень высокая. А вот кто писал monotone — не очень понятно. Может студенты, может "средние" программисты.
> все системы одинаково часто сравниваються во всяких обзорах и обладают примерно одинаковой функциональностью (и багами).
Допустим.
> Неужели вы верите в с++гениев недооцененных серой толпой голо-cишных-питон-программеров .
Ни в коем случае. Просто весьма вероятно, что примерно одинаковые системы написали сишные суперзвезды и серая толпа плюсовых кодеров.
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[5]: Линус о языке Си++
От:
Аноним
Дата:
13.12.07 12:10
Оценка:
Здравствуйте, Аноним, Вы писали:
MSS>>>Что сделал толкового Александреску и что сделал Линус? C>>Александреску написал книгу про С++. А вот президент Путин ничего не говорит про С++, а сколько он всего сделал! А>Да-да-да! Лучше бы он эту книгу не писал которую куча м...ов "прочитала", нихрена не поняла и давай писать программы в подобном стиле что поубивать хочется.
Вот давече прочитал эту книжку — очень понравилась , жду не дождусь когда предоставиться возможность использовать полученные знания
Здравствуйте, Maxim S. Shatskih, Вы писали:
AA>>Нет силы разрушительной страшнее, AA>>Чем кода стиль "Я-Прочитал-Александреску"...
MSS>После всего вот этого я начинаю понимать, что и не хочу читать Александреску
> S>"In other words, the only way to do good, efficient, and system-level and portable C++ ends up to limit yourself to all the things that are basically available in C." Ну это просто брехня. В C++ по крайней мере проверки типов построже и переменные непосредственно перед использованием объявлять можно. Насчет portable — я сильно удивлюсь, если GIT или тем более linux kernel вдруг скомпиляется чем-то отличным от gcc. > > Linux можно собрать интеловским компилятором, хотя и не без напильника.
Который специально имеет режим совместимости с gcc...
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, Roman Odaisky, Вы писали:
RO>Здравствуйте, Maxim S. Shatskih, Вы писали:
MSS>>http://article.gmane.org/gmane.comp.version-control.git/57918
RO>Баян, уже обсуждали.
RO>Линус, судя по всему, отстал от жизни. С тех пор C++, мягко говоря, изменился.
RO>Как-то же на C++ написали BeOS (и, кажется, NeXT). И не C++ виноват в том, что они исчезли.
NeXT, это, наверное, Обжектив С. Который та еще ересь.
Of course, the code must be complete enough to compile and link.
Здравствуйте, Константин Л., Вы писали:
Pzz>>Линус написал достаточно много кода своими собственными руками, чтобы к его мнению об инструментах имело смысл прислушиваться. Страуструп, кстати, тоже программист-практик, а не специалист-теоретик по языкам программирования. Теоретики занимаются лиспами, хаскелями и прочими ML'ями.
КЛ>однако даже Влад не опускается до такой ереси.
Здравствуйте, Maxim S. Shatskih, Вы писали:
C>>В Линуксе, например, бинарной совместимости вообще нет. И что? А вообще, лучше всего для бинарной совместимости на С++ использовать систему типа COM-интерфейсов. MSS>Это и есть описанное Линусом подмножество Си++. У микрософта в PortCls оно используется.
Если добавить темплейты, умные указатели и контейнеры — получится почти весь С++.
MSS>Ссылки и operator+ всякие, и особенно operator T — процентов на 90 есть абъюз. Толковых мест, где ими можно пользоваться, раз, два, и обчелся — только библиотеки строк и контейнеров.
Операторы +-/... — это да, их очень редко нужно. operator() — это хорошо для функторов подходит, которыми вполне можно и в ядре пользоваться.
Что еще? Умные указатели тоже очень неплохо во многие места вписываются. Ну и исключения тоже не помешали бы — как показывает опыт Windows, они вполне работают и в ядре.
MSS>Ссылки нужны на деле только для того, чтобы поддержать operator++, operator[] и прочее, где операнд или результат есть lvalue. Соответственно, ссылки вне параметров и возвращаемых значений — просто ненужная фича, и причем дурацкая, ибо неполноценно дублирует указатели. Неполноценно потому, что не бывает указателей на ссылки и массивов ссылок.
Нет. Ссылки, особенно константные ссылки, — это способ самодокументации кода. Если метод принимает константную ссылку — вызывающий может быть уверен, что метод не будет менять объект по этой ссылке (в разумном коде, естественно).
Многие ядерные разработчики вообще не понимают смысла константности — типа "и без const'а же работает". Вот сравнительно свежий пример: http://thread.gmane.org/gmane.linux.kernel/595956/focus=596197
MSS>Ссылки в параметрах и возвращаемых значениях оправданы только в operator XX, в обычной функции пойнтер лучше — в вызовах явно пишется &, что подсказывает, что параметр меняется в результате вызова. Запись f(a), от которой а изменилось, да еще и у f имя по-дурацки выбрано — мерзость.
Неконстантные ссылки — это вообще как раз редкость, именно по этой причине. Я вообще не могу вспомнить, когда я их в последний раз использовал. Хотя константные ссылки я использую везде.
Точнее нет, вру. Могу вспомнить — в реализации вывода в поток. Что еще раз подтверждает плохой дизайн системы потоков в С++.
Здравствуйте, Pzz, Вы писали:
Pzz>Здравствуйте, Cyberax, Вы писали:
C>>Нет. Ссылки, особенно константные ссылки, — это способ самодокументации кода. Если метод принимает константную ссылку — вызывающий может быть уверен, что метод не будет менять объект по этой ссылке (в разумном коде, естественно).
Pzz>Константные ссылки в этом плане ничем не лучше константных указателей.
Здравствуйте, Maxim S. Shatskih, Вы писали:
E>>А здесь http://video.google.com/videoplay?docid=6520647478274589397 Андрей Александреску мягко объяснил, что Линус смотрит на C++ со своей очень своеобразной колокольни.
MSS>Что сделал толкового Александреску и что сделал Линус?
Первый написал много толковых книг по вопросу практики примения одного из самых распространенных языков программирования современности. Что такого "архивеликого" сделал второй? Почему рядом с Линусом не поставить, например, Билла Гейтса? Кто из двух последних "вообще круче"?
Здравствуйте, The Lex, Вы писали:
А>>>Да-да-да! Лучше бы он эту книгу не писал которую куча м...ов "прочитала", нихрена не поняла и давай писать программы в подобном стиле что поубивать хочется. C>>Не волнуйся, без этой книги эти нехорошие люди писали бы точно так же плохо — но в обычном old C++-стиле TL>Есть факты "писания в стиле Александреску" без хотя бы мало-мальского понимания сути того "что зачем и как" пишешь?
Есть, к сожалению. Лично на себе наблюдал Правда, так как я себя знаю, то я это делал на игрушечных проектах.
Здравствуйте, Maxim S. Shatskih, Вы писали:
AA>>Нет силы разрушительной страшнее, AA>>Чем кода стиль "Я-Прочитал-Александреску"...
MSS>После всего вот этого я начинаю понимать, что и не хочу читать Александреску
Здравствуйте, Alxndr, Вы писали:
A>Здравствуйте, AndrewJD, Вы писали:
AJD>>Здравствуйте, ArtDenis, Вы писали:
AA>>>>Нет силы разрушительной страшнее, AA>>>>Чем кода стиль "Я-Прочитал-Александреску"...
AD>>>После прочтения александреску у меня не появилось желания писать в таком-же стиле, хотя возможность была AJD>>Значит ты уже зрелый профессионал. А вот на не окрепшие умы эта книга действует разрушительно
A>А что в ней такого разрушительного?
Слишком обобщенные решения для обычного прикладного программирования.
Здравствуйте, Cyberax, Вы писали:
Pzz>>Это плохая оптимизация — у нее слишком много тонких эффектов. Если что-то не может быть сделано прозрачно (а дешевая передача объектов в языке типа Си/C++ не может быть сделана прозрачно, в силу очень открытого интерфейса к реальной памяти машины), то лучше не делать этого вовсе. C>Можешь явно написать чем она плохая?
Тем, что я передаю вызываемой процедуре больше, чем хочу передать. А именно, право не просто узнать значение объекта, а еще и адрес, по которому это значение лежит.
Потом, constantness в C++ — понятие вообще довольно "плюшевое". В силу того, что C++ унаследовал от Си понятие о значении объекта, как о содержимом тех байтов памяти, из который состоит объект.
К примеру, взять такой объект:
struct str
{
char *s;
};
В буквальном C++'ном понимании его константность заключается в том, что я не смогу поменать указатель s. Но мне ничего не помешает пописать в память, на которую ссылается этот указатель. Изменится при этом значение объекта или нет? Формально — нет, ведь объект лишь содержит указатель, а он не поменялся. Однако если я в силу своего высокоуровнего абстрактного понимания считаю значением объекта именно содержание строки, на которую он ссылается, значение очевидно поменялось. При этом у меня нет синтаксического способа объяснить компилятору эту тонкую семантическую грань — разве что в комментарии написать, и надеяться, что кто-то (не компилятор!) его прочтет.
Здравствуйте, Pzz, Вы писали:
Pzz>Правило неиспользования STL, очевидно, не сработает вообще — если STL нельзя использовать, найдется умник, который напишет библиотеку с эквиавалентной функциональностью (только сильно недоделанную, поскольку писаться будет под конкретные нужды). А если начать запрещать использование отдельных фич C++, то в конечном итого от C++ ничего не останется. И проконтроллировать такой запрет, кстати, будет нелегко.
Тут я не понял "за" или "против" этот аргумент и "за или против" чего. Тут вот совсем недавно и совсем рядом девушка хотела аналог std::string, но чтобы работал на ANSI C. В результате имеет "те же яйца, только сбоку" (к)
S>>"infinite amounts of pain when they don't work" — ну это при использовании чужих библиотек завсегда бывает. Что характерно, если что-то don't work в своей библиотеке — amounts of pain из-за этого гораздо меньше (правда, работы больше). Но это, на мой взгляд, language-neutral feature. Лично меня приколы OpenSSL достали видимо ничуть не меньше, чем Линуса STL. Вот уж где
Pzz>C++ гораздо менее прозрачен, чем Си. Даже в C++ без темплейтов столько всего происходит неявно и автоматически, что глазками уже не проследишь. C++ с темплейтами делает вещи еще "интереснее".
Это да. На ANSI C такие вещи обычно упрятаны в старинную самописную библиотеку и "вытягиваются на свет божий" только в случае чего-то "крайне ахового". Только не надо говорить, якобы кто-нибудь пишет что-нибудь серьезное сегодня без использования какой-либо заранее созданной инфраструктуры — читай, framework-а. Просто на C++ он стандартный и реализован компилятором и рантаймом, а на Си — своими же или чужими ручками. Кстати, потому Си получается переносимее: "самописный рантайм" можно всегда либо пересобрать на практически любой платформе, либо еще и "доточить" по мере необходимости. Ну и, опять-таки, "сишный" "рантайм" может быть любого "веса" и "аппетита к ресурсам" по мере необходимости.
S>>Итого — С++ развращает программиста, поскольку для него есть слишком много библиотек, а в языке слишком много фич.
Pzz>Просто, слишком много фич. Чрезмерная сложность не является хорошим качеством инструмента. Hint: любители работают пассатижами и разводными ключами (т.е., универсальным инструментом). Профессионал пользуется большой коллекцией дорогущих специализированных ключей, каждый для своей гайки.
Тогда вам прямая дорога в .NET C# etc.: вот где настоящее раздолье для "большой коллекцией дорогущих специализированных ключей, каждый для своей гайки"! (к)
Pzz>Для того множества типов, которые доступны в обоих языках, строгость проверки их почти одинаковая.
Лично я, например, долго "палился" на собеседованиях на привычке возможности присваивания целого указателю...
Здравствуйте, eao197, Вы писали:
Pzz>>В буквальном C++'ном понимании его константность заключается в том, что я не смогу поменать указатель s. Но мне ничего не помешает пописать в память, на которую ссылается этот указатель. Изменится при этом значение объекта или нет? Формально — нет, ведь объект лишь содержит указатель, а он не поменялся. Однако если я в силу своего высокоуровнего абстрактного понимания считаю значением объекта именно содержание строки, на которую он ссылается, значение очевидно поменялось. При этом у меня нет синтаксического способа объяснить компилятору эту тонкую семантическую грань — разве что в комментарии написать, и надеяться, что кто-то (не компилятор!) его прочтет.
E>Могли бы вы назвать такой язык (из широкораспространненных, с достаточным количеством инструментария, библиотек и документации) в котором вы могли бы сделать компилятору такие указания?
> S>Фигня. Сущности, с которыми работает программа (класса — в случае С++), в любом случае приходится выделять, хоть на бейсике пиши, хоть на жабе. Разумеется, выделять их приходится на одной и той же стадии проектирования, независимо от языка. Причем, по моему опыту, кошмар от их неудачного выбора при написании программы на С бывает гораздо жОстче — во многом благодаря более слабой типизации. > > В Си нет такой вещи, как иерархия классов. А именно ее очень болезненно переделывать.
Т.е., если ровно то же мы реализовали (неправильно реализовали) без классов — то переделывать менее болезненно?
>>> Кроме того, кода на C++ тоже обычно получается больше, чем на Си, из-за более детального описания "правил игры" с объектами. > > S>Это кто как пишет. Лично у меня исходного кода на C++ обычно получается меньше — благодаря RAII и шаблонам. А вот объем бинарника больше — за счет более полной обработки ошибок. > > Сравнивать стили 2-х любых отдельно взятых человек нет смысла — индивидуальные особенности могут перевесить все особенности языка. В общем и целом, C++'ные программисты гораздо более детально описывают интерфейс (а кто так не делает — тот козел ), что приводит к раздуванию кода. Именно исходного кода, я имею ввиду.
Т.е., сишные программисты — козлы без вариантов? Ибо детально интерфейс не описывают... Ну-ну.
>>> Если ты — руководитель проекта, то очень трудно объяснять каждому следующему программисту, почему это мы используем, а это — нет. > > S>Ну у Линуса я гляжу вообще такой проблемы нет — piss of и усе Так чта мимо кассы. > > Линус в течении многих лет руководит большим проектом, в который вовлечено множество людей, и делает это вполне успешно. Разумеется, в его стиле руководства есть определенные недостатки, но в общем и целом это работает.
Годится. Никому ничего не объясняем, просто говорим — кто хочет использовать STL и не понимает, почему этого делать нельзя — идет нафиг.
> S>Возьмем к примеру простое правило — кто должен освобождать память? В плюсах это решается элементарно — разумется, объект, который этой памятью владеет. Вся стратегия выделения-освобождения-смены владельца прячется внутрь объекта. "Голые указатели" просто запрещаем. В С же придется все случаи, отличные от "стратегии по умолчанию" (например — кто выделил — тот и освобождает), отдельно документировать и, что самое поганое, периодически налетать на ситуацию когда кто-то из разработчиков оказался недостаточно внимателен. И, кроме управления памятью, таких примеров можно придумать массу. > > Глупость какая-то. В простых случаях ничего не стоит договориться о простых принципах управления памятью, и всем их соблюдать.
Речь идет, разумеется, о сложных случаях.
> Их можно даже поенфорсить,
Как конкретно будем энфорсить?
> как это делает внутри себя Apache — например, аллоцировать память со ссылкой на родительский объект, и обеспечить автоматическое удаление всей памяти, которой владеют дочерние объекты, при удалении родительского. Реализовать такую штуку не сильно сложнее, чем реализовать "вумственный" (smart) указатель.
Это называется "закат солнца вручную".
> > В сложных случаях (например, если Вы пишете систему управления памятью ядра операционной системы) такой простой подход все равно не сработает — на то они и сложные случаи. К счастию, эту сложность обычно удается локализовать.
У меня пока срабатывал. Впрочем, ядра ОС я пока и не писал.
> Потом, не забывайте, что кроме памяти есть и другие действия, которые надо совершать парно. Например, открывать/закрывать файлы, работать с объектами синхронизации и т.п.
Про RAII я кажется упоминал. Еще один камешек в огород С.
>>> Правило неиспользования STL, очевидно, не сработает вообще — если STL нельзя использовать, найдется умник, который напишет библиотеку с эквиавалентной функциональностью (только сильно недоделанную, поскольку писаться будет под конкретные нужды). > > S>Что характерно, при использовании С такую библиотеку по любому придется писать > > Мы ведь говорили о ядре линуха, нет?
Не только.
> В случае ядра, такую библиотеку придется писать в любом случае — STL, работающей в ядре, в природе не существует.
Это верно ровно до тех пор, пока мы не начали писать ядро на С++ Собственно, не вижу причин, по которым std::sort не будет работать в ядре.
>>> А если начать запрещать использование отдельных фич C++, то в конечном итого от C++ ничего не останется. И проконтроллировать такой запрет, кстати, будет нелегко. > > S>Не сложнее, чем проконтролировать следование стратегиям управления памятью > > Сложнее, потому что гораздо проще объяснить, что с памятью надо обращаться таким-то образом ("иначе работать не будет"), чем то, почему простые способы использования темплейтов разрешены, а использование темплейтов в стиле пресловутого Александреску — нет.
Не вижу ничего страшного в уместном применении шаблонов в стиле пресловутого Александреску. К тому же, научить качественно программировать на С ничуть не проще, чем научить писать сложные шаблоны только там, где от них реально есть польза.
>>> C++ гораздо менее прозрачен, чем Си. > > S>Есть такой момент. Хотя иногда это достоинство, а не недостаток. > > Это всегда недостаток. Не надо путать непрозрачность с высокоуровневостью.
Вот и не путай. Когда у меня в результате выбрасывания исключения "сами собой", благодаря деструкторам уничтожаются десяток другой временных объектов — это не только непрозрачность, но и высокоуровневость — потому что мне не пришлось ручками прописать тучу проверок возвращаемых значений и гору goto cleanup;
> Когда я в каком-нибудь, прости господи, Перле использую строки, мне глубоко наплевать, как они там собраны из отдельных байтов — они все равно ведут себя как строки. В C++ же их, строк, внутренний мир полностью скрыть невозможно — все равно что-нибудь да вылезет.
В чем конкретно заключаются ваши претензии к строкам? Они не ведут себя как строки? В С они ведут себя лучше?
>>> Речь, по-моему, идет не о "тормозении" кода, а о неадекватности выбранной абстракции. > > S>Насколько я понял, речь идет о торможении (или перерасходе памяти) из-за неверно выбранной абстракции. > > Я плохо помню, что писал Линус (и лень перечитывать). Но мое мнение, ментальные проблемы, связанные с неверным выбором абстракции, гораздо разрушительнее, чем любые проблемы с памятью и скоростью исполнения программы.
ментальные проблемы, связанные с неверным выбором абстракции, как я уже говорил, language-independent. Иначе это не абстракции.
>>> С чем может быть трудно что-то сделать, если большой объем кода от этой абстракции сильно зависит. > > S>Это — language-independent проблема. > > И да и нет. Эта проблема разрастается как снежный ком, если собирать абстракции в сложные иерархии. C++ очень способствует построению сложных иерархий, часто без нужды.
А С способствует низкоуровнему лазанью в структуры данных. Что на возможность рефакторинга влияет еще более губительно.
> При этом перетрясти уже имеющуюся иерархию очень сложно.
Поменять что-либо в написанной плохим С-программистом программе еще сложнее
>>> Чрезмерная сложность не является хорошим качеством инструмента. Hint: любители работают пассатижами и разводными ключами (т.е., универсальным инструментом). Профессионал пользуется большой коллекцией дорогущих специализированных ключей, каждый для своей гайки. > > S>Плохая аналогия. Если оставаться в рамках одного языка, то в С++ специализированных ключей больше, в то время как С — одни большие плоскогубцы. > > Один язык — один инструмент.
Вот-вот, плохая аналогия. Одним инструментом в любом случае много не наработаешь.
>>> Для того множества типов, которые доступны в обоих языках, строгость проверки их почти одинаковая. > > S>
> > S>В плюсах не скомпиляется. Ну и вообще, на голом C даже типобезопасный аналог printf не сделать. Или вот: > > Написав слово void, Вы попросили компилятор не лезть Вам в душу. Что компилятор и сделал. Вполне честные отношения. Случайно слово void не напишешь.
Отсюда вывод — С способствует написанию программ, обходящих систему типов.
> > Типобезопасный аналог printf и в C++ не сделаешь. Форматный вывод в поток — не аналог printf.
boost::format. Не идеал, но для вывода сообщений об ошибках — то, что надо.
> С точки зрения безопасности, не вижу особой разницы между ошибками, и предупреждениями. Просто не позволяйте себе оставлять в программе неисправленные предупреждения (или явно сделайте их ошибками, опцией компилятора).
В реальной жизни зачастую ни то, ни другое невозможно.
> S>Ну так и чего тогда трепаться про портабельность? Если вся его портабельность — 1 компилятор (хотя нет, еще интел в режиме совместимости) и 1 операционка. > > Скорее, это портабабельность трепаются апологеты C++.
"and anybody who tells me that STL and especially Boost are stable and portable is just so full of BS that it's not even funny"
"In other words, the only way to do good, efficient, and system-level and portable C++ ends up to limit yourself to all the things that are basically available in C."
>>> C++ тут не при чем. Портировать-то его, конечно, как-то портировали, но для полноценной поддержки Венды надо бы, как минимум, разобраться с \r\n, > > S>Это не отмаз — достаточно файлы в бинарном режиме открывать. > > Нет. Система управления исходными текстами должна позволать локально держать файлы с теми разделителями строк, которые приняты на данной системе.
И при этом не должна самовольно редактировать и форматировать мои исходники. Для этого более другие программы есть.
> Если 2 человека редактируют один и тот же текстовый файл, один из под виндов, другой из под униха,
Это уже более сложная задача — дайте мне хотя бы работать только из под виндов или только из под линукса. Нет даже этого.
> то содержимое файлов должно выглядеть для них одинаково, а разделители строк так, как принято на данной системе. Иначе очень неудобно.
Ну вот у меня буст локально лежит — там концы строк lf. И наши исходники — там как правило cr lf. Разница невооруженным глазом не видна и мне это нисколько не мешает. Что я делаю не так?
>>> с тем, что Виндовая файловая система не чувствительна к регистру > > S>Это вообще проблемы пользователя. > > Если делать продукт, а не поделку, это не проблема пользователя.
rar у нас значит поделка, не продукт... SVN тоже...
>>> и с тем, что надо что-то делать с юниксными правами доступа (очень раздражает, когда скрипты теряют битик, разрешающий их to execute, или наоборот, все файлы этот битик приобретают) > > S>Достаточно его не торогать, если коммит идет с системы, данный битик не поддерживающей. > > Его еще как-то хранить надо локально. Например, явно в метаинформации, которая связана с файлом в рабочей копии.
Ну и в чем проблема? Все равно кучу всякого трэша, связанного с файлом хранить надо — почему бы еще пару байт туда не добавить
>>> и с юниксными симлинками. > > S>Опять же, проблема пользователя. Не поддерживает ОС симлинки — не используй их. > > Если кто-то положил в репозиторий симлинк, как он должен выглядеть с точки зрения пользователя, который общается с системой контроля версий через виндовс?
Под вистой — как симлинк. Под более ранними — как ошибка.
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, Maxim S. Shatskih, Вы писали:
Pzz>>Это плохая оптимизация — у нее слишком много тонких эффектов. Если что-то не может быть сделано прозрачно (а дешевая передача объектов в языке типа Си/C++ не может быть сделана прозрачно, в силу очень открытого интерфейса к реальной памяти машины), то лучше не делать этого вовсе.
MSS>Как хорошо, что Си не дает передавать структуры by value... и временных объектов не плодит...
Здравствуйте, hexis, Вы писали:
H>Ну, тогда мы явно заблуждаемся вместе. Что такое "индустриальный" H>стиль программирования, как не эффективность на этапе разработки?
Для начала надо определить понятие эффективности. Но как бы не была определена эффективность, ясно, что она является дробью, в числителе у которой то, что мы преобрели, а в знаменателе — то, что потратили.
Индустриальный же способ разработки — это в первую очередь не эффективность как таковая, а масштабируемость. Т.е., сохранение эффективности более-менее неизменной при существенном увеличении потраченных ресурсов (например, числа разработчиков). Что позволяет в конечном итоге увеличить отдачу, просто вкладывая в проект дополнительные бапки.
Заметим в скобках, что если бабок мало, масштабируемость совершенно не нужна. В отличии от эффективности.
Здравствуйте, Pzz, Вы писали:
Pzz>Индустриальный же способ разработки — это в первую очередь не эффективность как таковая, а масштабируемость. Т.е., сохранение эффективности более-менее неизменной при существенном увеличении потраченных ресурсов (например, числа разработчиков). Что позволяет в конечном итоге увеличить отдачу, просто вкладывая в проект дополнительные бапки.
Нет такого — и никогда не было. Софт — это не единственный и далеко не новый "объект индустриального производства, нуждающийся в разработке". Тупо "масштабируются" при сохранении возможности создания конечного продука только рутинные операции: надо написать 100 буков "А" — можно посадить 1 человека, а можно 10, а можно и 100 — получим почти линейную масштабируемость. Если же надо написать "Войну и мир" — читай, "разработать" — масштабировать на уровне "чем больше наймем — тем лучше" никак не получится — и никогда не получалось. Еще раз: до софта была куча других промышленных объектов, которые точно так же проектировались, как софт — разрабатывается. И "просто масштабировать" производительность КБ, посадив 100 проектировщиков вместо 10 можно только на рутинных, четко определенных и ограниченных операциях, вроде черчения или расчетов.
Имхо, это дискуссия не для этого топика и не для этого раздела — это уже в "философию".
Pzz>Заметим в скобках, что если бабок мало, масштабируемость совершенно не нужна. В отличии от эффективности.
Тема бабок не раскрыта. Тема эффективности не раскрыта. Тема масштабируемости не раскрыта. Тема создания конечно продукта не раскрыта. Незачот.
Здравствуйте, Maxim S. Shatskih, Вы писали:
MSS>>>Как хорошо, что Си не дает передавать структуры by value... и временных объектов не плодит... RO>>С каких это пор не дает?
MSS>Когда я это последний раз пробовал сделать — получил warning, и тут же про это забыл. Зачем это нужно-то? если мне будет нужно by value — то я сам объявлю Tmp и сделаю Tmp = Struct; f(&Tmp); Делов-то
Во-первых, зачем так пренебрегать замечательными возможностями C99?
Здравствуйте, remark, Вы писали:
MSS>>>Почему не cout.output(i).output(j)? E>>Потому, что output -- это метод какого-то класса. И в C++ у меня нет возможности расширять чужой класс перегруженными методами для своих типов.
R>Хороший аргумент. Правда он не отменяет возможности писать: R>
R>output(cout, i);
R>output(cout, j);
R>
R>Это впрочем уже не так красиво...
Это недоработка. Такая же, как и public virtual. Должно было быть 2 функции, интерфейс и реализация. Т. е., юзеры перегружали бы одну функцию, а вызывали бы другую. Например:
x.h
class X
{
. . .
};
void output(std::ostream& os, X const& x) // тема basic_ostream сознательно оставлена за кадром
{
os << x.toString(); // например
}
Здравствуйте, Pzz, Вы писали:
S>>Фигня. Сущности, с которыми работает программа (класса — в случае С++), в любом случае приходится выделять, хоть на бейсике пиши, хоть на жабе. Разумеется, выделять их приходится на одной и той же стадии проектирования, независимо от языка. Причем, по моему опыту, кошмар от их неудачного выбора при написании программы на С бывает гораздо жОстче — во многом благодаря более слабой типизации. Pzz>В Си нет такой вещи, как иерархия классов. А именно ее очень болезненно переделывать.
Как нет?!?! Очень даже есть! Посмотри на GObject'ы в GTK, например.
То что иерархия классов не вносится на уровень языка — еще не означает, что на прикладном уровне ее не будет. Со всеми теми же проблемами, да еще и усиленными отсутствием контроля компилятора.
Pzz>Сравнивать стили 2-х любых отдельно взятых человек нет смысла — индивидуальные особенности могут перевесить все особенности языка. В общем и целом, C++'ные программисты гораздо более детально описывают интерфейс (а кто так не делает — тот козел ), что приводит к раздуванию кода. Именно исходного кода, я имею ввиду.
Эээ... Вообще-то, я лично переписывал драйвер с C-шного стиля на С++-ный — благодаря RAII код уменьшился в два раза. Pzz>Если кто-то положил в репозиторий симлинк, как он должен выглядеть с точки зрения пользователя, который общается с системой контроля версий через виндовс?
Здравствуйте, Cyberax, Вы писали:
Pzz>>Тем, что я передаю вызываемой процедуре больше, чем хочу передать. А именно, право не просто узнать значение объекта, а еще и адрес, по которому это значение лежит. C>А какие у тебя варианты еще? При передаче указателя — ты сразу передаешь адрес, а при передаче по значению — ты точно так же можешь взять адрес на временный объект.
Временный объект при передаче по значению — это локальная переменная вызываемой процедуры.
C>Тут Егор уже объяснил. Могу объяснить и я, если интересно.
Проще спорить с одним, чем с двумя. Выберете от себя делегата
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, The Lex, Вы писали:
TL>>
TL>>В настоящее время лишь около двух процентов системного ядра «Linux» написано самим Торвальдсом, но за ним остаётся решение о внесении изменений в официальную ветку ядра.
TL>>Это и есть "очень большой и серьезный проект"?
E>Ну там написано, что он этим проектом руководит...
Ну т.е. Торвальдс — это менеджер. Чего он полез с менеджерской колокольни судить о языке, которого он не знает — не очень понятно.
Здравствуйте, jazzer, Вы писали:
J>Ну т.е. Торвальдс — это менеджер. Чего он полез с менеджерской колокольни судить о языке, которого он не знает — не очень понятно.
Нет, Торвальдс — очень хороший программист. Но! Он системный программист, часто работающий на уровне ассемблера (он писал, что GDB в качестве дизассемблера чаще всего использует).
В результате — у него стандартная болезнь системщиков. Т.е. неприятие чего-либо кроме С.
Здравствуйте, Pzz, Вы писали:
C>>Как нет?!?! Очень даже есть! Посмотри на GObject'ы в GTK, например. Pzz>В Си нет такой вещи, как иерархоя классов. Ее можно при желании сделать ручками, но значительно меньше хочется, чем воспользоваться встроенной в C++. Поэтому без большой нужды делать не будешь.
И что? Если нужна иерархия — то и на С придется ее делать, или расставлять switch'и. Ну не вижу я тут проблемы.
Pzz>GTK писали студенты, это надо понимать. Им было прикольно.
Ну и?
C>>Эээ... Вообще-то, я лично переписывал драйвер с C-шного стиля на С++-ный — благодаря RAII код уменьшился в два раза. Pzz>Эээ. А я лично (командой из 3-х человек) выразил в 60К строк на Си примерно то, что команда из 6-и человек до меня выразила в 300К строк кода на C++. Поэтому у меня другой опыт.
Интересно, за счет чего? За счет оптимизации алгоритмов/структуры? Мы получили выигрыш просто за счет изменения стиля кода.
Здравствуйте, Maxim S. Shatskih, Вы писали:
RO>>Вообще, грустно в Windows без нормальных файловых систем. Например, FAT на флешках — это же издевательство над микросхемой…
MSS>А что, на флешке нужны симлинки? или rwxrwxrwx?
Нет, именно над микросхемой. У нее есть некое ограниченное, и не такое уж и большое, количество циклов чтения-записи (а точнее, стирания) на каждую ячейку. FAT использует пространство очень неравномерно, соответственно, когда она протрет дыру в начале раздела, где хранится собственно таблица, наступит виндекапец. Юниксукапец наступит значительно позже, потому что там есть JFFS2, специально созданная для флеш-памяти. Это особенно важно для новомодных безвинчестерных устройств вроде Asus Eee, где сама ОС живет на флешке. (NTFS/ext3/reiserfs ситуацию не исправят, потому что тоже рассчитаны на винчестеры.)
Симлинки нужны, rwxrwxrwx не нужны в том смысле, что юзер/группа всё равно будут другими на другом компьютере, в который флешка воткнута, и нужны в том, что потерять эти режимы при переносе даных с одного юникса на другой малоприятно (впрочем, здесь tar спасает отца русской демократии).
Здравствуйте, Pzz, Вы писали:
Pzz>Отчасти за счет того, что в C++'ном коде были очень дотошно расписаны правила игры в терминах интерфейсов — в Си так не сделаешь, поэтому и сделано не было. Отчасти же за счет того, что C++'ный код был более абстрактным и заточенным на дальнейшее развитие в неизвестно какую сторону, а Сишный был более сконцентрирован на решении практической задачи.
Это называется синдром YAGNI (You Ain't Gonna Need It) — если бы на С проектировали в таком же стиле, то объем кода был бы в разы больше С++ То есть, это опять проблемы не языка, а разработчиков.
Здравствуйте, remark, Вы писали:
C>>На практике, от включения исключений тормозов не заметно (кроме "эффектов второго порядка" от большего cache contention'а). R>А что за эффект cache contention'а при включении исключений? Можно поподробнее?
Код начинает занимать больший объем, а значит появляется больше шансов, что переход или вызов функции не попадут в кэш. На практике, такие эффекты почти не заметны, хотя в вырожденных случаях можно сделать замедление в разы.
R>Я правильно понял, что ты говоришь о ситуации, когда мы просто отключаем исключения в программе, которая на самом деле их использует, и тем самым фактически выключаем всю обработку ошибок (по крайней мере обработку нехватки памяти)?
Да, в качестве теста на верхнюю границу оверхеда — вполне подходит.
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, jazzer, Вы писали:
J>>Это где же Александреску говорил, что его решения — для прикладного программирования??? J>>А если какие-то идиоты принимаются писать прикладной код в стиле библиотечного кода, а гуй — на асме, а драйвер — на вижуал-бейсике — так это их персональные половые проблемы.
E>Да и в "Моей Борьбе" ничего такого в целом ненаписано. Но идиоты нашлись и находятся до сих пор... Может таки не толкьо в идиотах дело?
Это, батенька, закон Мерфи: "Какой бы исчерпывающей ни была инструкция, всегда найдется идиот, который сделает все наоборот и при этом будет утверждать, что в инструкции все именно так и написано".
Здравствуйте, jazzer, Вы писали:
J>Ну т.е. Торвальдс — это менеджер. Чего он полез с менеджерской
колокольни судить о языке, которого он не знает — не очень понятно.
Нет, Торвальдс — очень хороший программист. Но! Он системный
программист, часто работающий на уровне ассемблера (он писал, что GDB в
качестве дизассемблера чаще всего использует).
Cyberax пишет:
C> В результате — у него стандартная болезнь системщиков. Т.е. неприятие
чего-либо кроме С.
C> Sapienti sat!
Чего только не приплетут, и Линус больной системщик, и менеджер, и
колокольня у него уже не та. Что угодно, лишь бы не слышать
нежелательную информацию.
Здравствуйте, Left2, Вы писали:
J>>>Это где же Александреску говорил, что его решения — для прикладного программирования??? J>>>А если какие-то идиоты принимаются писать прикладной код в стиле библиотечного кода, а гуй — на асме, а драйвер — на вижуал-бейсике — так это их персональные половые проблемы.
E>>Да и в "Моей Борьбе" ничего такого в целом ненаписано. Но идиоты нашлись и находятся до сих пор... Может таки не толкьо в идиотах дело?
L>Только в них. Сам по себе майн кампф не стал бы причиной концлагерей. Книга сама по себе не в состоянии изменить этот мир, она только одно из средств пропаганды и агитации.
"Идеи, овладевая массами, становятся материальной силой"
Здравствуйте, Cyberax, Вы писали:
C>Я на Ada немного писал, но мне она показалась очень уже многословной. По фичам — больше похоже на какой-нибудь Оберон, но более заточеная на безопасность.
Говорят, у нее есть поддержка всякой там многопоточности прямо в языке...
Здравствуйте, OCTAGRAM, Вы писали:
OCT>Тут на днях один чувак конкурс выиграл OCT>( http://offline.computerra.ru/2007/712/341893/ ; «Успехи колоссальные») OCT>Цитирую его слова ( http://www.schlaupelz.de/SZ42/SZ42_software.html ):
И? Я точно такое же слышал про все остальные языки (включая COBOL).
OCT>Кто попало не выигрывает такие конкурсы, правда? Если вообще участвуют. OCT>Может, стоит уделить внимание его словам?
Ты знаешь, я как-то привык доверять моим ощущениям в тех областях, где я компетентен.
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Kluev, Вы писали:
K>>Я вот совсем не знаю Аду, но когда я вижу в коде begin/end моя рука сама тянется к пистолету.
E>Невроз наверное? Что такого страшного в begin/end?
Здравствуйте, Maxim S. Shatskih, Вы писали:
E>>А здесь http://video.google.com/videoplay?docid=6520647478274589397 Андрей Александреску мягко объяснил, что Линус смотрит на C++ со своей очень своеобразной колокольни.
MSS>Что сделал толкового Александреску и что сделал Линус?
А разве сейчас обсуждаются результаты трудов Торвальда и Александреску? Имхо, обсуждаются сказанные ими вещи. И Александреску правильно говорит, что у Торвальдса команда из сотен очень таланливых разработчиков, они занимаются достаточно специфическими задачами, у них нет жестко оговоренных сроков и бюджетов. В таких условиях C может быть отличным языком. Тем не менее вокруг полно задач, для которых есть сроки, бюджеты и гораздо меньшие команды. В таких условиях C вряд ли много лучше C++, скорее наоборот.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Sergey, Вы писали:
S>"In other words, the only way to do good, efficient, and system-level and portable C++ ends up to limit yourself to all the things that are basically available in C." Ну это просто брехня. В C++ по крайней мере проверки типов построже и переменные непосредственно перед использованием объявлять можно. Насчет portable — я сильно удивлюсь, если GIT или тем более linux kernel вдруг скомпиляется чем-то отличным от gcc.
Linux можно собрать интеловским компилятором, хотя и не без напильника. Говорят, будто от этого оно даже работает заметно быстрее.
Здравствуйте, AndrewJD, Вы писали:
AJD>Здравствуйте, ArtDenis, Вы писали:
AA>>>Нет силы разрушительной страшнее, AA>>>Чем кода стиль "Я-Прочитал-Александреску"...
AD>>После прочтения александреску у меня не появилось желания писать в таком-же стиле, хотя возможность была AJD>Значит ты уже зрелый профессионал. А вот на не окрепшие умы эта книга действует разрушительно
Здравствуйте, D. Mon, Вы писали:
RO>>Как-то же на C++ написали BeOS (и, кажется, NeXT). И не C++ виноват в том, что они исчезли. DM>А не Objective-C?
Нет, BeOS был написан на C++. В текущей Mac OS X в ядре тоже используется С++.
Здравствуйте, Maxim S. Shatskih, Вы писали:
C>>Александреску написал книгу про С++. А вот президент Путин ничего не говорит про С++, а сколько он всего сделал! MSS>Я бы не стал сравнивать Линуса и Путина. Линус, в отличие от Путина, сделал реально большое и приносящее пользу дело.
Дело в том, что Линус очень квалифицированый разработчик в некоторых областях. Так получилось, что для этих областей вполне подходит обычный С.
Почти все аргументы в его статье — просто смешны, мы тут уже это обсуждали даже.
MSS>А книга по Си++... вы знаете, что сказал халиф про книги и Коран, сжигая библиотеку в Александрии?
Ага.
MSS>так вот, Коран в области Си++ — это книги Страуструпа, иногда на пару с Эллис. Дальнейшее, я думаю, понятно
Но вот фича в том, что для того, чтобы не изучать Ко..., я хотел сказать ISO-IEC-14882, в течение всей жизни — неплохо бы иметь и другие книги.
У Александреску в книге был реально другой подход к построению программ на С++ рассмотрен.
Здравствуйте, Sash_xp, Вы писали:
S_>Помню, как-то один из создателей UNIX (Ричи, кажется). Сказал, что с архетикрутной точки зрения Linux -полный ноль.
По-моему, это был Таненбаум, и сказал он более-менее то, что с архитектурной точки зрения в линухе нет ничего нового.
Это не означает, что Линус идиот. Это лишь означает, что архитектура линуха довольно близко повторяет архитектуру уже существовавших до него веток юникса.
S_>А мораль, примерно такова: у кого-нибудь есть заблуждение, что Торвальдс является специалистом в области теории языков и С++ в частности?
Линус написал достаточно много кода своими собственными руками, чтобы к его мнению об инструментах имело смысл прислушиваться. Страуструп, кстати, тоже программист-практик, а не специалист-теоретик по языкам программирования. Теоретики занимаются лиспами, хаскелями и прочими ML'ями.
Здравствуйте, Pzz, Вы писали:
[]
S_>>А мораль, примерно такова: у кого-нибудь есть заблуждение, что Торвальдс является специалистом в области теории языков и С++ в частности?
Pzz>Линус написал достаточно много кода своими собственными руками, чтобы к его мнению об инструментах имело смысл прислушиваться. Страуструп, кстати, тоже программист-практик, а не специалист-теоретик по языкам программирования. Теоретики занимаются лиспами, хаскелями и прочими ML'ями.
Здравствуйте, Cyberax, Вы писали:
C> В текущей Mac OS X в ядре тоже используется С++.
Да, IOKit это с++, точнее говоря embedded c++, который по сути дела си-с-классами с кучей ограничений — стл, бустом и темплейтами там не пахнет.
Отдельная песня — это описание класса который позволяет изменения (добавление новых полей и виртуальных методов), при этом бинарно совместим
с предыдущей версией этого класса. Об этом и говорит Линус:
...
In other words, the only way to do good, efficient, and system-level and portable C++ ends up to limit yourself to all the things that are basically available in C.
...
Здравствуйте, Maxim S. Shatskih, Вы писали:
MSS>Микроядро там Mach и чистый Си, вокруг BSD-совместимая обертка, которая тоже чистый Си, сам движок Display PostScript — тоже чистый Си.
Я не сказал бы, что это "обертка" — ядро BSD там присутствует в полном составе. Я не очень в курсе, как они делят машину между mach'ем и BSD.
MSS>Objective C там на уровне гуевого фреймворка (уровень user32 и MFC в виндах).
Там есть еще фрамеворк для писания ядреных драйверов, на C++. Часть драйверов втыкается именно в него — например, сетевые драйвера.
MSS>>Я добавлю — в ядре виндов тоже практически нет Си++, и как-то они не горят желанием его туда тянуть. А аргументы Александреску против Линуса (что это опенсорс, никем толком не руководимый) к ядру виндов не относятся. C>Ну почему же? Вполне есть — многие драйвера его успешно используют.
До появления KDMF из микрософтного — только PortCls, FtDisk и 2мерный графический движок.
Си++ных АПИ в ядре нет и сейчас, даже с KMDF. KMDF и GRE обернуты в Сишный АПИ. Собственно, GREшный CLIPOBJ_bEnum — да, это CLIPOBJ::bEnum.
Pzz>Я не сказал бы, что это "обертка" — ядро BSD там присутствует в полном составе. Я не очень в курсе, как они делят машину между mach'ем и BSD.
Я слышал такое: Mach — это прерывания, объект "нить", объект "адресное пространство", половина системы VM — не хватает pager objects, которые туда можно полиморфно воткнуть, таймеры, kmalloc.
Вокруг Mach там BSD-совместимая обертка, в которой BSDшный объект "процесс", права доступа, тела сисколлов, pagerы для свопа и для mmap, и якобы еще и сеть там BSDшная и файловые системы.
Отдельно есть API для обычных драйверов, тех, что block и char, там есть, в частности, аналог динамической devfs/procfs или виндового IoRegisterDeviceInteface.
Настаивать не буду, слышал краем уха, возможно, у вас больше информации.
Pzz>Там есть еще фрамеворк для писания ядреных драйверов, на C++. Часть драйверов втыкается именно в него — например, сетевые драйвера.
Если на Си++ сделан АПИ для сетевых драйверов — то, похоже, там и IP стек не BSDшный. Я слышал другое, но совсем краем уха.
Здравствуйте, Maxim S. Shatskih, Вы писали:
Pzz>>Там есть еще фрамеворк для писания ядреных драйверов, на C++. Часть драйверов втыкается именно в него — например, сетевые драйвера.
MSS>Если на Си++ сделан АПИ для сетевых драйверов — то, похоже, там и IP стек не BSDшный. Я слышал другое, но совсем краем уха.
Этот C++'ный фрамеворк, похоже, втыкается в BSD. Сеть у Мака BSD'ная.
Здравствуйте, Pzz, Вы писали:
C>>Нет. Ссылки, особенно константные ссылки, — это способ самодокументации кода. Если метод принимает константную ссылку — вызывающий может быть уверен, что метод не будет менять объект по этой ссылке (в разумном коде, естественно). Pzz>Константные ссылки в этом плане ничем не лучше константных указателей.
Лучше. Константные ссылки — это по сути оптимизация передачи по значению. В частности, очень частно это делается при передаче временных объектов. Если же брать на них указатель — то мы не можем знать сохранит ли вызываемый код где-то у себя. В случае со ссылками мы знаем, что вызываемый код не будет сохранять переданое ему значение (ну если его не идиоты пишут, конечно).
Язык нам дает гарантию, что если мы не будем делать идиотских поступков — то у нас не будет проблем.
Здравствуйте, Pzz, Вы писали:
Pzz>>>Константные ссылки в этом плане ничем не лучше константных указателей. C>>Лучше. Константные ссылки — это по сути оптимизация передачи по значению. Pzz>Это плохая оптимизация — у нее слишком много тонких эффектов. Если что-то не может быть сделано прозрачно (а дешевая передача объектов в языке типа Си/C++ не может быть сделана прозрачно, в силу очень открытого интерфейса к реальной памяти машины), то лучше не делать этого вовсе.
Можешь явно написать чем она плохая?
C>>Язык нам дает гарантию, что если мы не будем делать идиотских поступков — то у нас не будет проблем. Pzz>При этом грань, отделяющая идиотский поступок от неидиотского столь тонка...
Нет. Нужно достаточно сильно постараться, чтобы ее перейти — создать объект, который в конструкторе принимает эту ссылку, и сохранить его. Это уже достаточно сложно сделать случайно
Здравствуйте, Sash_xp, Вы писали:
S_>Помню, как-то один из создателей UNIX (Ричи, кажется). Сказал, что с архетикрутной точки зрения Linux -полный ноль.
Угу. ОРни это говорили, когда Plan9 создавали. Только вот не получила их новая ОС популятности (а жаль, очч приятная штука вышла).
Здравствуйте, Cyberax, Вы писали:
C>В Линуксе, например, бинарной совместимости вообще нет. И что?
Ну макос — коммерческая ОС, а там бинарная совместимость необходима. А вот в линуксе как раз поиграться с с++ в ядре можно было (хотя может уже и игрались)
C>А вообще, лучше всего для бинарной совместимости на С++ использовать систему типа COM-интерфейсов.
Примерно это там и есть: OSObject.retain() == IUnknown.AddRef(), OSObject.release() == IUnknown.Release(), таблица виртуальных методов класса ==
IUnknown.lpVtbl.
C>Не согласен. Например, мне непонятен запрет template'ов — они реально помогают увеличить быстродействие без особого оверхеда.
Они позволяют убыстрить быстродействие когда вызовы инлайняться, так ведь? Это мало поможет для подгружаемых драйверов — хочешь не хочешь там
будут виртуальные вызовы.
C>STL — это, по сути, библиотека контейнеров, и они все равно нужны. В том же Линуксе, контейнеры делаются с помощью макросов (т.е. творчество на тему "темплейты своими руками").
Насколько я понимаю, использование макросов в ядре обусловлено интрузивностью (ну знаю как это по-русски сказать ) контейнеров. Есть специфичные структуры данных, оптимизированние для каких-то ядерных нужд, которых просто нет в стл. Кроме того темлейтные классы — это бинарный велосипед . Т.е. для каждого типа инстанцируется свой бинарный код, что, наверное, для режима ядра не очень хорошо: все же память в ядре — достаточно дорогой ресурс.
Линус прав в том смысле, что С++ в ядре места нет, а если и есть, то только как си-с-классами. В прикладных программах — скорее наоборот , тот же COM без ATL практически неподъеменый. Но там уже с++ следует сравнивать совсем не с "чистым си", а с явой/дотнетовыми языками.
> C>STL — это, по сути, библиотека контейнеров, и они все равно нужны. В том же Линуксе, контейнеры делаются с помощью макросов (т.е. творчество на тему "темплейты своими руками"). > Насколько я понимаю, использование макросов в ядре обусловлено интрузивностью (ну знаю как это по-русски сказать ) контейнеров. Есть специфичные структуры данных, оптимизированние для каких-то ядерных нужд, которых просто нет в стл.
И каким образом из отсутствия нужных структур данных в STL следует необходимость использования макросов, а не шаблонов?
> Кроме того темлейтные классы — это бинарный велосипед . Т.е. для каждого типа инстанцируется свой бинарный код,
Который потом линкером выкидывается — если код и вправду получился одинаковый. Причем это же справедливо и для макросов.
> Линус прав в том смысле, что С++ в ядре места нет, а если и есть, то только как си-с-классами.
Вообще-то он про GIT говорил...
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, Cyberax, Вы писали:
MSS>>>>Что сделал толкового Александреску и что сделал Линус? C>>>Александреску написал книгу про С++. А вот президент Путин ничего не говорит про С++, а сколько он всего сделал! А>>Да-да-да! Лучше бы он эту книгу не писал которую куча м...ов "прочитала", нихрена не поняла и давай писать программы в подобном стиле что поубивать хочется. C>Не волнуйся, без этой книги эти нехорошие люди писали бы точно так же плохо — но в обычном old C++-стиле
Есть факты "писания в стиле Александреску" без хотя бы мало-мальского понимания сути того "что зачем и как" пишешь?
Здравствуйте, ArtDenis, Вы писали:
AA>>Нет силы разрушительной страшнее, AA>>Чем кода стиль "Я-Прочитал-Александреску"...
AD>После прочтения александреску у меня не появилось желания писать в таком-же стиле, хотя возможность была
Объективные аргументы в обоснование имеются? Не для спора — интереса ради: конструктивную критику всегда приветствовал лично я.
Здравствуйте, Pzz, Вы писали:
C>>Нет. Ссылки, особенно константные ссылки, — это способ самодокументации кода. Если метод принимает константную ссылку — вызывающий может быть уверен, что метод не будет менять объект по этой ссылке (в разумном коде, естественно). Pzz>Константные ссылки в этом плане ничем не лучше константных указателей.
Pzz>При этом если я в Си передаю чего-нибудь по значению, это видно сразу в точке вызова. А в C++ надо посмотреть еще на прототип функции, чтобы узнать, не берет ли она от объекта ссылку вместо значения.
Непонятно в чем разница. Используйте константные ссылки если значение нельзя будет менять — т.е. если ссылка — "оптимизация передачи по значению": при этом точно не ошибетесь — компилятор не даст. В случае передачи по указателю... это указатель на единичный элемент или на массив? Это указатель получил валидный адрес, невалидный адрес (тот самый "указатель на временный объект из какой-то "третьей" функции), или просто null?
Имхо, ссылки в C++ — одна из самых удобных полезностей, к тому же лучше защищенная от "криворукости" программиста, чем указатели.
Pzz>Заметим также, что есть вещи, связанные с сылками, которые вообще остаются невидимыми. Например, функция, получившая адрес объекта, может за какой-нибудь надобностью его засейвить на будущее, что накладывает на меня обязательства не освобождать память, занятую этим объектом. В этом смысле, передача константной ссылки семантически очень отличается от передачи объекта по значению. Столь глубокое семантическое различие на мой взгляд заслуживает различия и в синтаксисе, причем в том месте, где объект передается, а не в том, где его принимают.
Здравствуйте, Pzz, Вы писали:
Pzz>>>Константные ссылки в этом плане ничем не лучше константных указателей. C>>Лучше. Константные ссылки — это по сути оптимизация передачи по значению.
Pzz>Это плохая оптимизация — у нее слишком много тонких эффектов. Если что-то не может быть сделано прозрачно (а дешевая передача объектов в языке типа Си/C++ не может быть сделана прозрачно, в силу очень открытого интерфейса к реальной памяти машины), то лучше не делать этого вовсе.
Имхо, это не "открытость интерфейса к реальной памяти" — это скорее "наследие адресной арифметики": по неновому уже стандарту первое попавшееся число указателю присвоить простым присваиванием нельзя. Имхо, совместимость в области адресной арифметики с ANSI C, включая некоторые ограничения — тоже одна из полезных фич, позволяющих в одном коде объединять и верхние уровни абстракции, и нижние — реализации.
C>>Язык нам дает гарантию, что если мы не будем делать идиотских поступков — то у нас не будет проблем.
Pzz>При этом грань, отделяющая идиотский поступок от неидиотского столь тонка...
Здравствуйте, The Lex, Вы писали:
TL>Первый написал много толковых книг по вопросу практики примения одного из самых распространенных языков программирования современности. Что такого "архивеликого" сделал второй?
Зато второй -- практик...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Sergey, Вы писали:
>> Насколько я понимаю, использование макросов в ядре обусловлено интрузивностью (ну знаю как это по-русски сказать ) контейнеров. S>И каким образом из отсутствия нужных структур данных в STL следует необходимость использования макросов, а не шаблонов?
Согласен, не следует, но для контейнера/структуры данных которая используеться один раз городить темплейтный класс наверное нет надобности, хотя это, конечно, не аргумент. Тогда конкретный вопрос — а вы можете посоветовать/показать какую-то библиотеку интрузивные темплейтных контейнеров (мой опыт работы с с++ небольшой и для него stl контейнеров вполне хватало)?
S>Который потом линкером выкидывается — если код и вправду получился одинаковый.
При динамической линковке не выкидываеться. Т.е если библиотека ядра содержыт класс template< class T > class IOService который является базовым для драйверов и
есть драйвер class DriverA : IOService< DriverA > и
есть еще один драйвер class DriverB : IOService< DriverB >,
то оба бинарника драйверов будут содержать копии IOService и при загрузке в ядро эти копии не выкинуться, даже если код будет одинаковым.
Теоретически, конечно же, можно писать части ядра на С++[1] (да и не только на нем), но практически — >> ... то только как си-с-классами.
S>Вообще-то он про GIT говорил...
В этой части веточки разговор был о с++ для ядра, а линус говорил о system-level and portable C++ (что в том числе и ядро и гит, по крайней мере, так я понимаю system-level). А даже если посмотреть на открытые системы контроля версий, то преимущества выбора с++(monotone) как языка реализации там совсем неочевидны, уже скорее "чистого си"(сvs,subversion,git) и питона(baazar,mercurial).
Все это конечно же под знаком IMHO .
[1] L4Ka::Pistachio microkernel, Fiasco µ-kernel — микроядра написанные на с++ и даже с темплейтами . Правда темплейты используються только для внутренней реализации — грубо говоря темплейтом задается архитектура под которую компилиться микроядро.
>>> Насколько я понимаю, использование макросов в ядре обусловлено интрузивностью (ну знаю как это по-русски сказать ) контейнеров. > S>И каким образом из отсутствия нужных структур данных в STL следует необходимость использования макросов, а не шаблонов? > > Согласен, не следует, но для контейнера/структуры данных которая используеться один раз городить темплейтный класс наверное нет надобности, хотя это, конечно, не аргумент.
Если сгородили макрос — значит и шаблон городить есть смысл
> Тогда конкретный вопрос — а вы можете посоветовать/показать какую-то библиотеку интрузивные темплейтных контейнеров (мой опыт работы с с++ небольшой и для него stl контейнеров вполне хватало)?
В бусте то ли уже появились, то ли вот-вот будут. А пока широко распространенных нету — и самому недолго написать.
> S>Который потом линкером выкидывается — если код и вправду получился одинаковый. > При динамической линковке не выкидываеться. Т.е если библиотека ядра > > содержыт класс template< class T > class IOService который является базовым для драйверов и > есть драйвер class DriverA : IOService< DriverA > и > есть еще один драйвер class DriverB : IOService< DriverB >, >> то оба бинарника драйверов будут содержать копии IOService и при загрузке в ядро эти копии не выкинуться, даже если код будет одинаковым.
Ситуация тут ровно та же, что и с макросами. И даже если все "руками написать", то — сюрприз — все равно две копии кода будут Так что в качестве аргумента против шаблонов — не катит.
> Теоретически, конечно же, можно писать части ядра на С++[1] (да и не только на нем), но практически - >>> ... то только как си-с-классами.
С классами и шаблонами... И кстати даже си-с-классами — уже совсем не "голый С". Система типов более строгая.
> S>Вообще-то он про GIT говорил... > В этой части веточки разговор был о с++ для ядра, а линус говорил о system-level and portable C++ (что в том числе и ядро и гит, по крайней мере, так я понимаю system-level).
С чего бы это система контроля версий вдруг стала system-level?
> А даже если посмотреть на открытые системы контроля версий, то преимущества выбора с++(monotone) как языка реализации там совсем неочевидны, уже скорее "чистого си"(сvs,subversion,git) и питона(baazar,mercurial).
Лень мне по их исходникам лазить... А без изучения — какое может быть сравнение? Да и квалификацию писателей все равно не учтешь.
> Все это конечно же под знаком IMHO . > > [1] L4Ka::Pistachio microkernel, Fiasco µ-kernel — микроядра написанные на с++ и даже с темплейтами . Правда темплейты используються только для внутренней реализации — грубо говоря темплейтом задается архитектура под которую компилиться микроядро.
А никто и не предлагает интерфейсы плюсовые наружу выставлять...
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
S>"C++ leads to really really bad design choices". — усе так и есть. C не позволяет схалтурить, объем исходников на С получается больше, поэтому горячим парням приходится сначала подумать а уж потом кодить С плюсами же можно по-быстрому налабать прототипчик и потом постепенно его дотачивать.
В реальности все строго наоборот. C++ (вообще, ООП) прощает все, кроме неудачного разбиения программы на классы. К сожалению, разбивать ее на классы приходится рано, когда нет достаточной ясности, как программа будет устроена. Поэтому вероятность разбить ее на классы неудачно очень велика.
Кроме того, кода на C++ тоже обычно получается больше, чем на Си, из-за более детального описания "правил игры" с объектами.
S>"You invariably start using the "nice" library features of the language like STL and Boost and other total and utter crap" — тут логика отсутствует. Не хочешь — не используй.
Если ты — руководитель проекта, то очень трудно объяснять каждому следующему программисту, почему это мы используем, а это — нет. Проще иметь некоторые универсальные правила, которым все должны следовать. Причем сами по себе правила должны быть простыми, иначе их никто не удосужится дочитать до конца. И следовать, соответственно, не будет.
Правило неиспользования STL, очевидно, не сработает вообще — если STL нельзя использовать, найдется умник, который напишет библиотеку с эквиавалентной функциональностью (только сильно недоделанную, поскольку писаться будет под конкретные нужды). А если начать запрещать использование отдельных фич C++, то в конечном итого от C++ ничего не останется. И проконтроллировать такой запрет, кстати, будет нелегко.
S>"infinite amounts of pain when they don't work" — ну это при использовании чужих библиотек завсегда бывает. Что характерно, если что-то don't work в своей библиотеке — amounts of pain из-за этого гораздо меньше (правда, работы больше). Но это, на мой взгляд, language-neutral feature. Лично меня приколы OpenSSL достали видимо ничуть не меньше, чем Линуса STL. Вот уж где
C++ гораздо менее прозрачен, чем Си. Даже в C++ без темплейтов столько всего происходит неявно и автоматически, что глазками уже не проследишь. C++ с темплейтами делает вещи еще "интереснее".
S>"inefficient abstracted programming models where two years down the road you notice that some abstraction wasn't very efficient, but now all your code depends on all the nice object models around it, and you cannot fix it without rewriting your app." Ну собственно это надо быть очень меедленным программистом (проще говоря, тупым тормозом), чтобы пару лет не замечать, что чего-то там круто тормозит.
Речь, по-моему, идет не о "тормозении" кода, а о неадекватности выбранной абстракции. С чем может быть трудно что-то сделать, если большой объем кода от этой абстракции сильно зависит.
S>Итого — С++ развращает программиста, поскольку для него есть слишком много библиотек, а в языке слишком много фич.
Просто, слишком много фич. Чрезмерная сложность не является хорошим качеством инструмента. Hint: любители работают пассатижами и разводными ключами (т.е., универсальным инструментом). Профессионал пользуется большой коллекцией дорогущих специализированных ключей, каждый для своей гайки.
S>"In other words, the only way to do good, efficient, and system-level and portable C++ ends up to limit yourself to all the things that are basically available in C." Ну это просто брехня. В C++ по крайней мере проверки типов построже и переменные непосредственно перед использованием объявлять можно. Насчет portable — я сильно удивлюсь, если GIT или тем более linux kernel вдруг скомпиляется чем-то отличным от gcc.
Для того множества типов, которые доступны в обоих языках, строгость проверки их почти одинаковая.
S>"So I'm sorry, but for something like git, where efficiency was a primary objective, the "advantages" of C++ is just a huge mistake." — ну собственно вольному воля. Аргументация, правда, по-прежнему отсутствует.
Это да. Mercurial написан вообще на Питоне, и при этом не сказать, что тормозит. И в отличии от Git'а, неплохо работает на Венде.
S>Ну а дальше он собственно Monotone ругает — не знаю, может она и правда "horrible and unmaintainable mess", но чето в этом сомневаюсь. Она, по крайней мере, почему-то Cygwin для запуска под виндой не требует — в отличие от "portable" GIT. Т.е., "horrible and unmaintainable mess" на винду портировали, а portable и mantainable — нифига.
Ну то, что Git не работает на Венде — вполне сознательная позиция Линуса. C++ тут не при чем. Портировать-то его, конечно, как-то портировали, но для полноценной поддержки Венды надо бы, как минимум, разобраться с \r\n, с тем, что Виндовая файловая система не чувствительна к регистру и с тем, что надо что-то делать с юниксными правами доступа (очень раздражает, когда скрипты теряют битик, разрешающий их to execute, или наоборот, все файлы этот битик приобретают) и с юниксными симлинками.
Здравствуйте, Константин Л., Вы писали:
Pzz>>И как из того, что там написано следует, что я сказал ересь?
КЛ>Ок, сорри, ты меня не понял. Линус сказал ересь, а не ты.
Здравствуйте, The Lex, Вы писали:
Pzz>>При этом если я в Си передаю чего-нибудь по значению, это видно сразу в точке вызова. А в C++ надо посмотреть еще на прототип функции, чтобы узнать, не берет ли она от объекта ссылку вместо значения.
TL>Непонятно в чем разница.
Разница в том, что вызываемая процедура получает не значение объекта, а его адрес. Это как платить не деньгами, а пластиковой картой — вы не просто отдаете продавцу 10 баксов, Вы авторизуете его покопаться в Вашем банковском счете. Как только Вам попадется нечестный (или просто неаккуратный) продавец, Вы сразу поймете, что это не одно и то же.
Здравствуйте, Pzz, Вы писали:
Pzz>В буквальном C++'ном понимании его константность заключается в том, что я не смогу поменать указатель s. Но мне ничего не помешает пописать в память, на которую ссылается этот указатель. Изменится при этом значение объекта или нет? Формально — нет, ведь объект лишь содержит указатель, а он не поменялся. Однако если я в силу своего высокоуровнего абстрактного понимания считаю значением объекта именно содержание строки, на которую он ссылается, значение очевидно поменялось. При этом у меня нет синтаксического способа объяснить компилятору эту тонкую семантическую грань — разве что в комментарии написать, и надеяться, что кто-то (не компилятор!) его прочтет.
Могли бы вы назвать такой язык (из широкораспространненных, с достаточным количеством инструментария, библиотек и документации) в котором вы могли бы сделать компилятору такие указания?
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Pzz, Вы писали:
Pzz>>>При этом если я в Си передаю чего-нибудь по значению, это видно сразу в точке вызова. А в C++ надо посмотреть еще на прототип функции, чтобы узнать, не берет ли она от объекта ссылку вместо значения.
TL>>Непонятно в чем разница.
Pzz>Разница в том, что вызываемая процедура получает не значение объекта, а его адрес. Это как платить не деньгами, а пластиковой картой — вы не просто отдаете продавцу 10 баксов, Вы авторизуете его покопаться в Вашем банковском счете. Как только Вам попадется нечестный (или просто неаккуратный) продавец, Вы сразу поймете, что это не одно и то же.
Угу. У вас прямая аналогия и прямое заблуждение, выведенное из этой аналогии.
Получается что когда вы передаете объект по значению — вы передаете продавцу весь свой счет — точнее, конечно, если прямо без оптимизации — его копию. хех! или же копию 10 баксов.
Вообще-то при расчете банковской картой максимум, к чему получает доступ продавец — это к "транзакции на 10 баксов" — которую, к тому же, вы до определенного момента можете еще и опротестовать...
Давайте без аналогий. Чем мешает передача по ссылке, а не по значению. При условии, что Си++ позволяет явно указать что ссылка — константная. Можно без него — тоже интересно. И насколько распространена практика передачи по значению более или менее сложных объектов (структур?) в Си.
Здравствуйте, The Lex, Вы писали:
TL>Здравствуйте, Pzz, Вы писали:
Pzz>>Правило неиспользования STL, очевидно, не сработает вообще — если STL нельзя использовать, найдется умник, который напишет библиотеку с эквиавалентной функциональностью (только сильно недоделанную, поскольку писаться будет под конкретные нужды). А если начать запрещать использование отдельных фич C++, то в конечном итого от C++ ничего не останется. И проконтроллировать такой запрет, кстати, будет нелегко.
TL>Тут я не понял "за" или "против" этот аргумент и "за или против" чего. Тут вот совсем недавно и совсем рядом девушка хотела аналог std::string, но чтобы работал на ANSI C. В результате имеет "те же яйца, только сбоку" (к)
Этот аргумент утверждает следующее: если Вы не хотите, чтобы в Вашем проекте появился STL, не используйте язык, на котором STL можно написать. Ничего другого не сработает.
Проблема с STL заключается не в том, что в нем реализуются автоматические растущие строки (они и до STL были, кстати) а в том, что в STL непонятно, что происходит — весь содержательный код выводится большим количеством весьма нетривиальных темплейтов.
Pzz>>C++ гораздо менее прозрачен, чем Си. Даже в C++ без темплейтов столько всего происходит неявно и автоматически, что глазками уже не проследишь. C++ с темплейтами делает вещи еще "интереснее".
TL>Это да. На ANSI C такие вещи обычно упрятаны в старинную самописную библиотеку и "вытягиваются на свет божий" только в случае чего-то "крайне ахового".
Я не про это. Я про то, что в случае Си гораздо проще проследить код до того, что там происходит на самом деле. В C++ сделано очень многое, чтобы усложнить такой анализ.
Pzz>>Просто, слишком много фич. Чрезмерная сложность не является хорошим качеством инструмента. Hint: любители работают пассатижами и разводными ключами (т.е., универсальным инструментом). Профессионал пользуется большой коллекцией дорогущих специализированных ключей, каждый для своей гайки.
TL>Тогда вам прямая дорога в .NET C# etc.: вот где настоящее раздолье для "большой коллекцией дорогущих специализированных ключей, каждый для своей гайки"! (к)
Это другая крайность. Это скорее коллекция специализированных гаек, пользоваться которыми можно вовсе без ключей.
Pzz>>Для того множества типов, которые доступны в обоих языках, строгость проверки их почти одинаковая.
TL>Лично я, например, долго "палился" на собеседованиях на привычке возможности присваивания целого указателю...
Без явного каста такое присваивание выдает предупреждение. С явным кастом можно и в C++ присвоить.
А на собеседования, на которых задают идиотские вопросы про редко используемые фичи языка ходить не надо — целее будете.
Здравствуйте, The Lex, Вы писали:
TL>Можно без него — тоже интересно. И насколько распространена практика передачи по значению более или менее сложных объектов (структур?) в Си.
Не насколько не распостранена. Но факт передачи указателя явно виден в точке вызова. Т.е., когда Вы читаете вызов функции, Вам не надо заглядывать в другой файл, чтобы понять, что на самом деле получит эта функция — значение или ссылку.
> S>"C++ leads to really really bad design choices". — усе так и есть. C не позволяет схалтурить, объем исходников на С получается больше, поэтому горячим парням приходится сначала подумать а уж потом кодить С плюсами же можно по-быстрому налабать прототипчик и потом постепенно его дотачивать. > > В реальности все строго наоборот. C++ (вообще, ООП) прощает все, кроме неудачного разбиения программы на классы. К сожалению, разбивать ее на классы приходится рано, когда нет достаточной ясности, как программа будет устроена. Поэтому вероятность разбить ее на классы неудачно очень велика.
Фигня. Сущности, с которыми работает программа (класса — в случае С++), в любом случае приходится выделять, хоть на бейсике пиши, хоть на жабе. Разумеется, выделять их приходится на одной и той же стадии проектирования, независимо от языка. Причем, по моему опыту, кошмар от их неудачного выбора при написании программы на С бывает гораздо жОстче — во многом благодаря более слабой типизации.
> Кроме того, кода на C++ тоже обычно получается больше, чем на Си, из-за более детального описания "правил игры" с объектами.
Это кто как пишет. Лично у меня исходного кода на C++ обычно получается меньше — благодаря RAII и шаблонам. А вот объем бинарника больше — за счет более полной обработки ошибок.
> S>"You invariably start using the "nice" library features of the language like STL and Boost and other total and utter crap" — тут логика отсутствует. Не хочешь — не используй. > > Если ты — руководитель проекта, то очень трудно объяснять каждому следующему программисту, почему это мы используем, а это — нет.
Ну у Линуса я гляжу вообще такой проблемы нет — piss of и усе Так чта мимо кассы.
> Проще иметь некоторые универсальные правила, которым все должны следовать. Причем сами по себе правила должны быть простыми, иначе их никто не удосужится дочитать до конца. И следовать, соответственно, не будет.
Возьмем к примеру простое правило — кто должен освобождать память? В плюсах это решается элементарно — разумется, объект, который этой памятью владеет. Вся стратегия выделения-освобождения-смены владельца прячется внутрь объекта. "Голые указатели" просто запрещаем. В С же придется все случаи, отличные от "стратегии по умолчанию" (например — кто выделил — тот и освобождает), отдельно документировать и, что самое поганое, периодически налетать на ситуацию когда кто-то из разработчиков оказался недостаточно внимателен. И, кроме управления памятью, таких примеров можно придумать массу.
> Правило неиспользования STL, очевидно, не сработает вообще — если STL нельзя использовать, найдется умник, который напишет библиотеку с эквиавалентной функциональностью (только сильно недоделанную, поскольку писаться будет под конкретные нужды).
Что характерно, при использовании С такую библиотеку по любому придется писать
> А если начать запрещать использование отдельных фич C++, то в конечном итого от C++ ничего не останется. И проконтроллировать такой запрет, кстати, будет нелегко.
Не сложнее, чем проконтролировать следование стратегиям управления памятью
> S>"infinite amounts of pain when they don't work" — ну это при использовании чужих библиотек завсегда бывает. Что характерно, если что-то don't work в своей библиотеке — amounts of pain из-за этого гораздо меньше (правда, работы больше). Но это, на мой взгляд, language-neutral feature. Лично меня приколы OpenSSL достали видимо ничуть не меньше, чем Линуса STL. Вот уж где > > C++ гораздо менее прозрачен, чем Си.
Есть такой момент. Хотя иногда это достоинство, а не недостаток.
> Даже в C++ без темплейтов столько всего происходит неявно и автоматически, что глазками уже не проследишь.
Зато сколько кода надо написать, чтобы покрыть те операции, за которыми глазками уже не проследишь...
> C++ с темплейтами делает вещи еще "интереснее".
А че про исключения забыл?
> S>"inefficient abstracted programming models where two years down the road you notice that some abstraction wasn't very efficient, but now all your code depends on all the nice object models around it, and you cannot fix it without rewriting your app." Ну собственно это надо быть очень меедленным программистом (проще говоря, тупым тормозом), чтобы пару лет не замечать, что чего-то там круто тормозит. > > Речь, по-моему, идет не о "тормозении" кода, а о неадекватности выбранной абстракции.
Насколько я понял, речь идет о торможении (или перерасходе памяти) из-за неверно выбранной абстракции.
> С чем может быть трудно что-то сделать, если большой объем кода от этой абстракции сильно зависит.
Это — language-independent проблема.
> S>Итого — С++ развращает программиста, поскольку для него есть слишком много библиотек, а в языке слишком много фич. > > Просто, слишком много фич.
И все равно не хватает...
> Чрезмерная сложность не является хорошим качеством инструмента. Hint: любители работают пассатижами и разводными ключами (т.е., универсальным инструментом). Профессионал пользуется большой коллекцией дорогущих специализированных ключей, каждый для своей гайки.
Плохая аналогия. Если оставаться в рамках одного языка, то в С++ специализированных ключей больше, в то время как С — одни большие плоскогубцы.
> S>"In other words, the only way to do good, efficient, and system-level and portable C++ ends up to limit yourself to all the things that are basically available in C." Ну это просто брехня. В C++ по крайней мере проверки типов построже и переменные непосредственно перед использованием объявлять можно. Насчет portable — я сильно удивлюсь, если GIT или тем более linux kernel вдруг скомпиляется чем-то отличным от gcc. > > Для того множества типов, которые доступны в обоих языках, строгость проверки их почти одинаковая.
void * q;
char *t;
q = 0;
t = q;
В плюсах не скомпиляется. Ну и вообще, на голом C даже типобезопасный аналог printf не сделать. Или вот:
int foo(int a)
{
return a * a;
}
int bar(int b)
{
return foo("s");
}
VC это спокойно компиляет — правда, выдает предупреждение.
> S>Ну а дальше он собственно Monotone ругает — не знаю, может она и правда "horrible and unmaintainable mess", но чето в этом сомневаюсь. Она, по крайней мере, почему-то Cygwin для запуска под виндой не требует — в отличие от "portable" GIT. Т.е., "horrible and unmaintainable mess" на винду портировали, а portable и mantainable — нифига. > > Ну то, что Git не работает на Венде — вполне сознательная позиция Линуса.
Ну так и чего тогда трепаться про портабельность? Если вся его портабельность — 1 компилятор (хотя нет, еще интел в режиме совместимости) и 1 операционка.
> C++ тут не при чем. Портировать-то его, конечно, как-то портировали, но для полноценной поддержки Венды надо бы, как минимум, разобраться с \r\n,
Это не отмаз — достаточно файлы в бинарном режиме открывать.
> с тем, что Виндовая файловая система не чувствительна к регистру
Это вообще проблемы пользователя.
> и с тем, что надо что-то делать с юниксными правами доступа (очень раздражает, когда скрипты теряют битик, разрешающий их to execute, или наоборот, все файлы этот битик приобретают)
Достаточно его не торогать, если коммит идет с системы, данный битик не поддерживающей.
> и с юниксными симлинками.
Опять же, проблема пользователя. Не поддерживает ОС симлинки — не используй их.
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, Pzz, Вы писали:
TL>>... Имхо, совместимость в области адресной арифметики с ANSI C, включая некоторые ограничения — тоже одна из полезных фич, позволяющих в одном коде объединять и верхние уровни абстракции, и нижние — реализации.
Pzz>Это наследие совместимости с Си. В Си такая открытость к аппаратуре была сделана вполне сознательно. В C++'е она мешает созданию нормальных высокоуровневых абстракций. В первую очередь потому, что трудно полностью скрыть тот факт, что управление памятью осталось ручным. И что любые объекты — всего лишь байты в памяти.
Pzz>Если бы язык проектировался начисто, а не рос из Си, как само растется, вполне можно было бы от source level совместимости с Си отказаться, но предусмотреть способ взаимного procedure calls между языками. Тем более, что там от этой совместимости уже сейчас мало чего осталось.
Да вроде все, что и было — даже виртуальные таблицы "плюсов" при желании без проблем можно из Си "дергать" — просто сами "плюсы" сравнительно далеко ушли...
Pzz>>>При этом грань, отделяющая идиотский поступок от неидиотского столь тонка... TL>>В ANSI C она еще тоньше. имхо.
Pzz>Си значительно проще и прозрачнее. Это большое достоинство.
А также недостаток: для выражения (написания, высказывания, реализации) простых вещей на "плюсах" на Си приходится "крепко материться".
Здравствуйте, Maxim S. Shatskih, Вы писали:
MSS>Ссылки нужны на деле только для того, чтобы поддержать operator++, operator[] и прочее, где операнд или результат есть lvalue. Соответственно, ссылки вне параметров и возвращаемых значений — просто ненужная фича, и причем дурацкая, ибо неполноценно дублирует указатели. Неполноценно потому, что не бывает указателей на ссылки и массивов ссылок.
Может немного не в тему, но тем не менее. Что мне не нравится в указателях и нравится в ссылках.
Указатель может представлять из себя 4 совершенно разные вещи:
1. Указатель на объект
2. Указатель на объект или 0
3. Массив объектов
4. Массив объектов или 0
При этом нет способа различить эти вещи, не вдаваясь в код, ни программисту, ни компилятору (по крайней мере никто это не делает).
Допустим есть некая незнакомая функция f(X* x). Как со стороны вызывающего, так и со стороны разработчика функции совершенно не понятно, что перечисленных 4 пунктов можно передать в эту функцию. Единственный способ — разбираться в коде функции, как она его использует. Допустим мы разобрались. Но компилятор это разбирать не будет — допустим функция ждёт один объект, а мы передаём туда массив или 0.
Далее, т.к. указатели обычно не объявляются как константные, то указатель-параметр в середине функции может вдруг "стать другим объектом". Ясности это тоже не прибавляет.
Всё это справедливо и для локальных переменных-указателей, и особенно для членов класса-указателей, т.к. у них scope больше и больше мест, где он может измениться, либо использовать как-то по другому.
Ссылка всегда представляет одну чётко определённую вещь — это объект, всегда один, и никогда не отсутствие объекта (NULL). Поэтому сразу снимаются все вопросы и для вызывающего функцию, и для разрабатывающего функцию. Плюс к этому ссылка никогда не может "стать другим объектом" посередине функции, она всегда останется "входным" параметром функции.
Лично для меня это существенно повышает понятность кода.
Возможно формально ссылка является излишней вещью в языке... так же как и struct в C
Здравствуйте, Sergey, Вы писали:
S>Фигня. Сущности, с которыми работает программа (класса — в случае С++), в любом случае приходится выделять, хоть на бейсике пиши, хоть на жабе. Разумеется, выделять их приходится на одной и той же стадии проектирования, независимо от языка. Причем, по моему опыту, кошмар от их неудачного выбора при написании программы на С бывает гораздо жОстче — во многом благодаря более слабой типизации.
В Си нет такой вещи, как иерархия классов. А именно ее очень болезненно переделывать.
>> Кроме того, кода на C++ тоже обычно получается больше, чем на Си, из-за более детального описания "правил игры" с объектами.
S>Это кто как пишет. Лично у меня исходного кода на C++ обычно получается меньше — благодаря RAII и шаблонам. А вот объем бинарника больше — за счет более полной обработки ошибок.
Сравнивать стили 2-х любых отдельно взятых человек нет смысла — индивидуальные особенности могут перевесить все особенности языка. В общем и целом, C++'ные программисты гораздо более детально описывают интерфейс (а кто так не делает — тот козел ), что приводит к раздуванию кода. Именно исходного кода, я имею ввиду.
>> Если ты — руководитель проекта, то очень трудно объяснять каждому следующему программисту, почему это мы используем, а это — нет.
S>Ну у Линуса я гляжу вообще такой проблемы нет — piss of и усе Так чта мимо кассы.
Линус в течении многих лет руководит большим проектом, в который вовлечено множество людей, и делает это вполне успешно. Разумеется, в его стиле руководства есть определенные недостатки, но в общем и целом это работает.
S>Возьмем к примеру простое правило — кто должен освобождать память? В плюсах это решается элементарно — разумется, объект, который этой памятью владеет. Вся стратегия выделения-освобождения-смены владельца прячется внутрь объекта. "Голые указатели" просто запрещаем. В С же придется все случаи, отличные от "стратегии по умолчанию" (например — кто выделил — тот и освобождает), отдельно документировать и, что самое поганое, периодически налетать на ситуацию когда кто-то из разработчиков оказался недостаточно внимателен. И, кроме управления памятью, таких примеров можно придумать массу.
Глупость какая-то. В простых случаях ничего не стоит договориться о простых принципах управления памятью, и всем их соблюдать. Их можно даже поенфорсить, как это делает внутри себя Apache — например, аллоцировать память со ссылкой на родительский объект, и обеспечить автоматическое удаление всей памяти, которой владеют дочерние объекты, при удалении родительского. Реализовать такую штуку не сильно сложнее, чем реализовать "вумственный" (smart) указатель.
В сложных случаях (например, если Вы пишете систему управления памятью ядра операционной системы) такой простой подход все равно не сработает — на то они и сложные случаи. К счастию, эту сложность обычно удается локализовать.
Потом, не забывайте, что кроме памяти есть и другие действия, которые надо совершать парно. Например, открывать/закрывать файлы, работать с объектами синхронизации и т.п.
>> Правило неиспользования STL, очевидно, не сработает вообще — если STL нельзя использовать, найдется умник, который напишет библиотеку с эквиавалентной функциональностью (только сильно недоделанную, поскольку писаться будет под конкретные нужды).
S>Что характерно, при использовании С такую библиотеку по любому придется писать
Мы ведь говорили о ядре линуха, нет? В случае ядра, такую библиотеку придется писать в любом случае — STL, работающей в ядре, в природе не существует.
>> А если начать запрещать использование отдельных фич C++, то в конечном итого от C++ ничего не останется. И проконтроллировать такой запрет, кстати, будет нелегко.
S>Не сложнее, чем проконтролировать следование стратегиям управления памятью
Сложнее, потому что гораздо проще объяснить, что с памятью надо обращаться таким-то образом ("иначе работать не будет"), чем то, почему простые способы использования темплейтов разрешены, а использование темплейтов в стиле пресловутого Александреску — нет.
>> C++ гораздо менее прозрачен, чем Си.
S>Есть такой момент. Хотя иногда это достоинство, а не недостаток.
Это всегда недостаток. Не надо путать непрозрачность с высокоуровневостью. Когда я в каком-нибудь, прости господи, Перле использую строки, мне глубоко наплевать, как они там собраны из отдельных байтов — они все равно ведут себя как строки. В C++ же их, строк, внутренний мир полностью скрыть невозможно — все равно что-нибудь да вылезет.
>> Даже в C++ без темплейтов столько всего происходит неявно и автоматически, что глазками уже не проследишь.
S>Зато сколько кода надо написать, чтобы покрыть те операции, за которыми глазками уже не проследишь...
C++ очень этому помогает
>> C++ с темплейтами делает вещи еще "интереснее".
S>А че про исключения забыл?
Память дырявая
>> Речь, по-моему, идет не о "тормозении" кода, а о неадекватности выбранной абстракции.
S>Насколько я понял, речь идет о торможении (или перерасходе памяти) из-за неверно выбранной абстракции.
Я плохо помню, что писал Линус (и лень перечитывать). Но мое мнение, ментальные проблемы, связанные с неверным выбором абстракции, гораздо разрушительнее, чем любые проблемы с памятью и скоростью исполнения программы.
>> С чем может быть трудно что-то сделать, если большой объем кода от этой абстракции сильно зависит.
S>Это — language-independent проблема.
И да и нет. Эта проблема разрастается как снежный ком, если собирать абстракции в сложные иерархии. C++ очень способствует построению сложных иерархий, часто без нужды. При этом перетрясти уже имеющуюся иерархию очень сложно.
>> Просто, слишком много фич.
S>И все равно не хватает...
Да, примерно как с кокаином
>> Чрезмерная сложность не является хорошим качеством инструмента. Hint: любители работают пассатижами и разводными ключами (т.е., универсальным инструментом). Профессионал пользуется большой коллекцией дорогущих специализированных ключей, каждый для своей гайки.
S>Плохая аналогия. Если оставаться в рамках одного языка, то в С++ специализированных ключей больше, в то время как С — одни большие плоскогубцы.
Один язык — один инструмент.
>> Для того множества типов, которые доступны в обоих языках, строгость проверки их почти одинаковая.
S>
S>void * q;
S>char *t;
S>q = 0;
S>t = q;
S>
S>В плюсах не скомпиляется. Ну и вообще, на голом C даже типобезопасный аналог printf не сделать. Или вот:
Написав слово void, Вы попросили компилятор не лезть Вам в душу. Что компилятор и сделал. Вполне честные отношения. Случайно слово void не напишешь.
Типобезопасный аналог printf и в C++ не сделаешь. Форматный вывод в поток — не аналог printf.
S>
S>int foo(int a)
S>{
S>return a * a;
S>}
S>int bar(int b)
S>{
S>return foo("s");
S>}
S>
S>VC это спокойно компиляет — правда, выдает предупреждение.
С точки зрения безопасности, не вижу особой разницы между ошибками, и предупреждениями. Просто не позволяйте себе оставлять в программе неисправленные предупреждения (или явно сделайте их ошибками, опцией компилятора).
S>Ну так и чего тогда трепаться про портабельность? Если вся его портабельность — 1 компилятор (хотя нет, еще интел в режиме совместимости) и 1 операционка.
Скорее, это портабабельность трепаются апологеты C++.
>> C++ тут не при чем. Портировать-то его, конечно, как-то портировали, но для полноценной поддержки Венды надо бы, как минимум, разобраться с \r\n,
S>Это не отмаз — достаточно файлы в бинарном режиме открывать.
Нет. Система управления исходными текстами должна позволать локально держать файлы с теми разделителями строк, которые приняты на данной системе. Если 2 человека редактируют один и тот же текстовый файл, один из под виндов, другой из под униха, то содержимое файлов должно выглядеть для них одинаково, а разделители строк так, как принято на данной системе. Иначе очень неудобно.
>> с тем, что Виндовая файловая система не чувствительна к регистру
S>Это вообще проблемы пользователя.
Если делать продукт, а не поделку, это не проблема пользователя.
>> и с тем, что надо что-то делать с юниксными правами доступа (очень раздражает, когда скрипты теряют битик, разрешающий их to execute, или наоборот, все файлы этот битик приобретают)
S>Достаточно его не торогать, если коммит идет с системы, данный битик не поддерживающей.
Его еще как-то хранить надо локально. Например, явно в метаинформации, которая связана с файлом в рабочей копии.
>> и с юниксными симлинками.
S>Опять же, проблема пользователя. Не поддерживает ОС симлинки — не используй их.
Если кто-то положил в репозиторий симлинк, как он должен выглядеть с точки зрения пользователя, который общается с системой контроля версий через виндовс?
Здравствуйте, Pzz, Вы писали:
Pzz>Этот аргумент утверждает следующее: если Вы не хотите, чтобы в Вашем проекте появился STL, не используйте язык, на котором STL можно написать. Ничего другого не сработает.
Да? Извините, но вы в каком-то странном окружении работает. Если в проекте есть правило "мы не используем stl" — то, конечно, должно быть хоть какое-то формальное обоснование такого решение, а то, понимаешь, встречаются проекты в которых есть мощнейшие архитектурно-организационные ограничения (например: мы всегда шифруем наши данные) — а вот ответа на вопрос "а почему так?" уже давно нет — потому как его давно банально забыли: да, была когда-то такая необходимость — так решили. Актуально ли это решение сейчас? А кто его знает — ведь никто уже не знает почему так решили.
Что касается "ничего другого не сработает", то я сталкивался с проектами, написанными на Си, на котором, в свою очередь, реализована весьма продвинутая логика "аля си плюс-плюс". И ответ на вопрос "почему так?" — "потому что так сделано заказчиком и нам надо сопровождать, а не переделывать" — меня, почему-то, вполне удовлетворял. Неужели я уже тогда был такой замшелый пофигист, что не стал спорить, а просто делал свою работу?
TL>>Это да. На ANSI C такие вещи обычно упрятаны в старинную самописную библиотеку и "вытягиваются на свет божий" только в случае чего-то "крайне ахового".
Pzz>Я не про это. Я про то, что в случае Си гораздо проще проследить код до того, что там происходит на самом деле. В C++ сделано очень многое, чтобы усложнить такой анализ.
Угу. Вообще-то это не так — это раз. А если это так, то, имхо, вы "копаетесь в песке и рассматриваете цветные камешки", вместо того чтобы "строить шоссе на 8 полос". Может у вас такая специфика, но подавляющему большинству реальных проектов это просто не нужно.
Кстати, низкоуровневый код — а точнее, HAL — таки и правда "ближе и проще" на "простом си". Вот только как только начинаются абстракции — как тут же самое время разделить слои и писать ниже нижнего на чем-то более подходящем, вместо того чтобы сперва реализовывать своими руками "что-то более подходящее", а потом уже "строить абстракции" на его базе. имхо.
TL>>Тогда вам прямая дорога в .NET C# etc.: вот где настоящее раздолье для "большой коллекцией дорогущих специализированных ключей, каждый для своей гайки"! (к)
Pzz>Это другая крайность. Это скорее коллекция специализированных гаек, пользоваться которыми можно вовсе без ключей.
Странные у вас аналогии. Имхо, они неправильные — но я готов согласиться что я их просто не понимаю.
Pzz>>>Для того множества типов, которые доступны в обоих языках, строгость проверки их почти одинаковая. TL>>Лично я, например, долго "палился" на собеседованиях на привычке возможности присваивания целого указателю...
Pzz>Без явного каста такое присваивание выдает предупреждение. С явным кастом можно и в C++ присвоить.
Только что проверил: например VC++ 7.1 выдает "error C2440: 'initializing' : cannot convert from 'int' to 'int *'" на следующую строку:
int i = 0;
int* pi = 0;
int* pi2 = i; // ошибка в этой строке
Могу проверить на gcc и на hpux cc еще.
Да, с явным кастом работает — я знаю. Но это надо _явно_ сказать "хочу привести к указателю". Тогда reinterpret_cast вообще всю систему типов порушит к ...
Pzz>А на собеседования, на которых задают идиотские вопросы про редко используемые фичи языка ходить не надо — целее будете.
Здравствуйте, The Lex, Вы писали:
Pzz>>Потом, constantness в C++ — понятие вообще довольно "плюшевое". В силу того, что C++ унаследовал от Си понятие о значении объекта, как о содержимом тех байтов памяти, из который состоит объект.
TL>Прямо скажем, это просто порочная практика "любителей копаться там, где никому больше не нужно": почему-то любимый вопрос на собеседовании "как по-вашему представлен экзепляр класса бинарно?" — на практике полезности не вызывает.
Я пытаюсь сказать несколько более глубокую вещь. Не то, что в C++ можно добраться до бинарной сущности объекта — ну можно и можно, и хрен бы с ним. А то, что в C++ нельзя спрятать эту бинарную сущность так, чтобы она никогда не вылезла при добросовестном использовании.
Проблема в том, что в C++ управление памятью — ручное. Как его не оборачивай в темплейтные обертки, компилятор все равно не в курсе, что происходит с памятью. А без этого, видимо, высокоуровневый язык не построишь.
TL>Ну ладно: как ты то же самое ограничишь в Си? А никак. TL>В тех же "плюсах" это может ограничить даже школьник, перебросив член в защищенную область и нарисовав публичные аксессоры. TL>Применить к C++ явно "сишный" подход и поставить факт в укор "плюсам" —
На C++, на самом деле, тоже толком никак. Например потому, что конструктор не знает, конструирует ли он константный или mutable объект. Си хоть не обещает невозможного. Честность — большое достоинство.
Здравствуйте, The Lex, Вы писали:
TL>Ключевой момент был неоднократно упомянут и указан явно тоже: практик в _чем_ именно?
В программировании довольно сложных систем. А Александреску практик в написании книжек...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
C>Нет. Ссылки, особенно константные ссылки, — это способ самодокументации кода. Если метод принимает константную ссылку — вызывающий может быть уверен, что метод не будет менять объект по этой ссылке (в разумном коде, естественно).
Понимаете, ядерные разработчики не только ядро знают зачастую я знаю, что const — это хорошо.
Но я не виноват, что Катлер с Луковским его невзлюбили и сделали все ядерные (и половину Win32шных) АПИ без него (кажется, Линус его тоже не любит). В итоге, чтобы не морочиться с кастами, приходится это "отсутствие const" волочь за собой везде и всюду.
C>Лучше. Константные ссылки — это по сути оптимизация передачи по значению. В частности, очень частно это делается при передаче временных объектов. Если же брать на них указатель — то мы не можем знать сохранит ли вызываемый код где-то у себя. В случае со ссылками мы знаем, что вызываемый код не будет сохранять переданое ему значение (ну если его не идиоты пишут, конечно).
Вот про идиотов хорошая оговорка. Идиоты могут передать ссылку в конструктор какого-то класса и позвать его через new.
Можно в комментарии к функции оговорить время жизни объекта, и имеет ли право функция сохранять данный указатель где-то.
Здравствуйте, Maxim S. Shatskih, Вы писали:
C>>Нет. Ссылки, особенно константные ссылки, — это способ самодокументации кода. Если метод принимает константную ссылку — вызывающий может быть уверен, что метод не будет менять объект по этой ссылке (в разумном коде, естественно).
MSS>Не согласен. Чем плохо const T* ?
Здравствуйте, Maxim S. Shatskih, Вы писали:
E>>Как человек, которому на C++ довелось посчитать математику (в том числе и с матрицами комплексных чисел в 99-2000-й годах)
MSS>Вот конкретно матрицы и есть тот редкий случай, когда operator — по делу.
Ну с матрицами вопрос спорный. operator[] для разных хитрых матриц -- да, по делу. А вот разные operator+ или operator* -- тут можно и к expression templates приплыть.
А вот примеры с std::complex или какими-то другими типами, выдающими себя за числа -- это как раз показательно.
E>>и сделать несколько систем сериализации/десериализации данных
MSS>Зачем overloading для этого? << как запись куда-то — это неинтуитивно. Кроме того, операция 2местная, а если туда надо format spec передать?
format spec -- это к сериализации/десериализации не относится, особенно к двоичной.
MSS>Почему не cout.output(i).output(j)?
Потому, что output -- это метод какого-то класса. И в C++ у меня нет возможности расширять чужой класс перегруженными методами для своих типов. Если кто-то сделает, например:
class asn_1_per_stream_t
{
public :
void
output( const asn_1_object_t & what );
...
};
То это значит, что кроме asn_1_object_t я в поток поместить не смогу. Что разработчик класса asn_1_per_stream_t придумал для output -- только то и можно использовать.
А в случае с перегрузкой операторов можно сделать сдвиг в asn_1_per_stream_t любых объектов, даже тех, которые от asn_1_object_t не производны, но могут через них выражаться. Например, объект ACE_Date_Time.
И в случае с перегрузкой операторов можно получить a) единообразное поведение для любых типов (в том числе для тех, о которых разработчик библиотеки даже не догадывался) и b) расширение списка типов, на которые данная операция распространяется.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Pzz, Вы писали:
Pzz>>>Потом, constantness в C++ — понятие вообще довольно "плюшевое". В силу того, что C++ унаследовал от Си понятие о значении объекта, как о содержимом тех байтов памяти, из который состоит объект. TL>>Прямо скажем, это просто порочная практика "любителей копаться там, где никому больше не нужно": почему-то любимый вопрос на собеседовании "как по-вашему представлен экзепляр класса бинарно?" — на практике полезности не вызывает. :xz: Pzz>Я пытаюсь сказать несколько более глубокую вещь. Не то, что в C++ можно добраться до бинарной сущности объекта — ну можно и можно, и хрен бы с ним. А то, что в C++ нельзя спрятать эту бинарную сущность так, чтобы она никогда не вылезла при добросовестном использовании.
std::vector<int> const someIntegers(42u, 42);
там наверняка внутри три указателя — начало данных, конец данных, конец выделенной области памяти. Как ты этот вектор ни используй, данные ты не изменишь. Спрятано всё.
Pzz>Проблема в том, что в C++ управление памятью — ручное. Как его не оборачивай в темплейтные обертки, компилятор все равно не в курсе, что происходит с памятью. А без этого, видимо, высокоуровневый язык не построишь.
Открою секрет: в C++09 изо всех сил стараются добавить GC. Ручное управление памятью — не проблема.
TL>>Ну ладно: как ты то же самое ограничишь в Си? А никак. TL>>В тех же "плюсах" это может ограничить даже школьник, перебросив член в защищенную область и нарисовав публичные аксессоры. :user: TL>>Применить к C++ явно "сишный" подход и поставить факт в укор "плюсам" — :???: :no: :xz:
Pzz>На C++, на самом деле, тоже толком никак. Например потому, что конструктор не знает, конструирует ли он константный или mutable объект.
Это лишено смысла… X const x = X(); — здесь какой объект конструируется?
Здравствуйте, Maxim S. Shatskih, Вы писали:
R>>Допустим есть некая незнакомая функция f(X* x).
MSS>Комментарии надо писать, и пользоваться T Array[] и T* Ptr.
Во-первых, это не защищает от возможности подумать, что можно передать 0.
Во-вторых, к сожалению, так пишет очень мало программистов, и главное разработчики библиотек типа WinAPI.
R>>Далее, т.к. указатели обычно не объявляются как константные
MSS>Можно и объявить. Как и ссылку.
Ссылки всегда константные.
Опять же понятно, что можно написать и [], и комментарий, и const. Но я говорю о реальной жизни. Достаточно открыть первую попавшуюся библиотеку и с вероятностью 80% там этого ничего не будет.
Здравствуйте, Maxim S. Shatskih, Вы писали:
C>>Лучше. Константные ссылки — это по сути оптимизация передачи по значению. В частности, очень частно это делается при передаче временных объектов. Если же брать на них указатель — то мы не можем знать сохранит ли вызываемый код где-то у себя. В случае со ссылками мы знаем, что вызываемый код не будет сохранять переданое ему значение (ну если его не идиоты пишут, конечно).
MSS>Вот про идиотов хорошая оговорка. Идиоты могут передать ссылку в конструктор какого-то класса и позвать его через new.
MSS>Можно в комментарии к функции оговорить время жизни объекта, и имеет ли право функция сохранять данный указатель где-то.
Это делается с помощью shared_ptr и weak_ptr, проще и надежнее.
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, Maxim S. Shatskih, Вы писали:
E>>>Как человек, которому на C++ довелось посчитать математику (в том числе и с матрицами комплексных чисел в 99-2000-й годах)
MSS>>Вот конкретно матрицы и есть тот редкий случай, когда operator — по делу.
E>Ну с матрицами вопрос спорный. operator[] для разных хитрых матриц -- да, по делу. А вот разные operator+ или operator* -- тут можно и к expression templates приплыть.
E>А вот примеры с std::complex или какими-то другими типами, выдающими себя за числа -- это как раз показательно.
Да. Причём таких примеров можно привести множество: даты и интервалы времени, суммы денег, числа произвольной длины, хранящиеся в строках и т.д.
MSS>>Почему не cout.output(i).output(j)?
E>Потому, что output -- это метод какого-то класса. И в C++ у меня нет возможности расширять чужой класс перегруженными методами для своих типов.
Хороший аргумент. Правда он не отменяет возможности писать:
Здравствуйте, Erop, Вы писали:
TL>>Ключевой момент был неоднократно упомянут и указан явно тоже: практик в _чем_ именно? E>В программировании довольно сложных систем. А Александреску практик в написании книжек...
Я в Линусе чайник: что еще кроме линукса Линус написал?
Здравствуйте, Sergey, Вы писали:
>>>> и с юниксными симлинками. >> S>Опять же, проблема пользователя. Не поддерживает ОС симлинки — не используй их. >> Если кто-то положил в репозиторий симлинк, как он должен выглядеть с точки зрения пользователя, который общается с системой контроля версий через виндовс?
S>Под вистой — как симлинк. Под более ранними — как ошибка.
Во-первых, здесь дело не в ОС, а в ФС, а во-вторых, какого рода ошибка?
Вообще, грустно в Windows без нормальных файловых систем. Например, FAT на флешках — это же издевательство над микросхемой…
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, The Lex, Вы писали:
TL>>Первый написал много толковых книг по вопросу практики примения одного из самых распространенных языков программирования современности. Что такого "архивеликого" сделал второй?
E>Зато второй -- практик...
Есть еще один практик, не менее великий, чем Торвальдст. Его зовут Кен Томпсон. Вот, что он когда-то говорил о Линуксе http://www.osp.ru/os/1999/04/179809/ ...
Здравствуйте, The Lex, Вы писали:
TL>Я в Линусе чайник: что еще кроме линукса Линус написал?
Не помню. Мни и линукса вполне достаточно. Это очень большой и серьёзный проект
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
По порядку, от сложного к простому
S>А никто и не предлагает интерфейсы плюсовые наружу выставлять...
Т.е. вернулись к началу ветки — к плоским COM-подобным интерфейсам (по сути — таблица с указателями на функции). Кроме того такое плоское апи уменьшает сцепление — оно не зависит даже от языка реализации интерфейса (это азы кома, вроде бы).
С классическими монолитными ядрами вроде уже никто не работает — динамически подружаемые модули составляют существенную часть работающего ядра. Апи подсистем ядра для этих модулей должно быть плоское. Подсистемы ядра общаються между собой и тоже, в идеале, должны обладать плоским апи (вдруг мы захотим сменить ну, например, шедулятор ). Но темлейты не дают нам такой гибкости, точнее, темплейты завернутые в плоский апи теряют всю свою темплейтность. Попробуйте придумать/написать плоскую обертку для stl — получиться что-то вроде at&tшной сdt (с кучей указателей на функции и void * в качестве контейнерного элемента).
Плоский апи — это границы применения темплейтов, также граница использования исключений, множественного наследование, rtti и прочих особенностей с++. Вроде бы сразу появляеться антипример — сильно-теплейтная АТЛ для плоского COM вполне существует и является вобщем state-of-art библиотекой. Но вот тут и возникает отличие — реализуя в коме свой IStream, вы одновременно реализуете свой ISequentialStream и свой IUnknown. Однако в ядре вы, реализуя свой IStream, должны использовать предоставленный системой ISequentialStream которой в свою очередь будет использовать предоставляемый системой IUnknown (это аналогия, не буквально). Допустим я пишу свой драйвер для сетевого юсб-девайса. Я должен предоставить интерфейс outputPacket(const void * raw, size_t size), зарегить его в системе и получить от системы интерфейс для юсб. В методе я заполняю USBPacket и вызваю у юсб-интерфейса метод usbSendCommand(USBPacket somePacket). Все. Тут (в заполнении структуры USBCommand) негде разгуляться всем фичам с++.
Кратко:
1) современное ядро ос не монолитно и представляет собой большое количество модулей, причем часть модулей подгружаеться/выгружаеться в рантайме.
2) модули выполняют какую-то одну относительно несложную задачу.
3) для выполнения каких-то запросов эти модули выстраиваются в стек и разные уровни стека между собой общаются на плоском апи.
В результате размеры и сложность этих модулей становятся небольшими, их внешние интерфесы — плоскими. А это ведет к тому что в ядре
1) не подходит тот шаблонный подход к проектированию, который используеться для билиотек типа стл, атл, буста.
2) полноценный с++ оказываеться просто не нужен, и полное его использование приводит к овердизайну.
Хотя принципиально никто не мешает использовать туже стл в ядре. Но вобщем никто и не мешает написать само ядро на пэ-ха-пэ или луа, у них есть даже одно преимущество перед с++ — сборка мусора
S>В бусте то ли уже появились, то ли вот-вот будут. А пока широко распространенных нету — и самому недолго написать.
Я понял — известных реализаций типа queue.h нет. Ну на нет и суда нет, хотя отелось бы посмотреть как это будет выглядеть в темплейтах с++.
S>Ситуация тут ровно та же, что и с макросами. И даже если все "руками написать", то — сюрприз — все равно две копии кода будут Так что в качестве аргумента против шаблонов — не катит.
тут не макросы vs шаблоны, а "шаблонный" подход к проектированию vs плоский комоподобный апи. А макросы против шаблонов почти всегда не катят — это очевидно.
S>С чего бы это система контроля версий вдруг стала system-level?
Требование к софту программеров и не_программеров разные (правда общий момент есть — чтобы работало и не глючило ). Поэтому ядро, службы/демоны, средства разработки — все то, что не решает проблемы пользователя-не_программиста я отношу к system-level. Возможно у меня сильно шырокое определение system-level , спорить не буду.
S>Лень мне по их исходникам лазить... А без изучения — какое может быть сравнение? Да и квалификацию писателей все равно не учтешь.
Да одинаковые у них квалификации, все системы одинаково часто сравниваються во всяких обзорах и обладают примерно одинаковой функциональностью (и багами). Неужели вы верите в с++гениев недооцененных серой толпой голо-cишных-питон-программеров .
TL>Я в Линусе чайник: что еще кроме линукса Линус написал?
7 лет назад был 15 мег зип с исходниками. Конечно, там не все один Линус писал, но он писал самые старые и фундаментальные вещи и еще и поддерживал все это как тимлид.
MSS>>Как хорошо, что Си не дает передавать структуры by value... и временных объектов не плодит...
RO>С каких это пор не дает?
Когда я это последний раз пробовал сделать — получил warning, и тут же про это забыл. Зачем это нужно-то? если мне будет нужно by value — то я сам объявлю Tmp и сделаю Tmp = Struct; f(&Tmp); Делов-то
Я думаю, что в целом Линус прав, но кое в чем он ошибается. Просто у
этих языков — принципиально разные цели. Настолько разные, что их, по
большому счету, не имеет особого смысла сравнивать. C++ (как и все ОО
языки), в первую очередь, ориентирован на эффективность разработки и
сопровождения программы, а C — на эффективность исполнения (память,
скорость, объем кода). Самое интересное, что стиль программирования
действительно меняется с языком. Происходит это за счет того, что язык
поощряет определенные решения, упрощая процесс их реализации. Как
правило, программы, написанные одним и тем же человеком на C, обычном
C++, при помощи метапрограммирования на C++ или функциональных языков,
имеют принципиально различные проектные решения.
Вот и получается, что выбрав в качестве одной из первичных целей
эффективность исполнения, им пришлось намеренно отказаться от C++.
Конечно, на C++ тоже можно писать эффективные программы (как и на C —
неэффективные). Просто для этого, как правило, приходится прилагать
больше усилий и тщательнее контролировать себя. В тоже время, существует
множество задач, где использование C++ оправданно и желательно.
Здравствуйте, Erop, Вы писали:
TL>>Я в Линусе чайник: что еще кроме линукса Линус написал? E>Не помню. Мни и линукса вполне достаточно. Это очень большой и серьёзный проект
Цитата из Википедии: (да, более достоверных источников... да мне просто лень искать )
В настоящее время лишь около двух процентов системного ядра «Linux» написано самим Торвальдсом, но за ним остаётся решение о внесении изменений в официальную ветку ядра.
Торвальдс владеет товарным знаком «Linux» и следит за его использованием[4] через некоммерческую организацию «Linux International» и при помощи пользователей «Linux» во всём мире.
Это и есть "очень большой и серьезный проект"?
Голь на выдумку хитра, однако...
Re[13]: Ты просто неверно понимаешь концепцию константности
Здравствуйте, Pzz, Вы писали:
Pzz>К примеру, взять такой объект:
Pzz>
Pzz>struct str
Pzz>{
Pzz> char *s;
Pzz>};
Pzz>
Pzz>В буквальном C++'ном понимании его константность заключается в том, что я не смогу поменать указатель s. Но мне ничего не помешает пописать в память, на которую ссылается этот указатель. Изменится при этом значение объекта или нет?
Ты просто плохо понимаешь концепцию константности в С++.
AFAIK, в C++ всё устроено как-то так
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Maxim S. Shatskih, Вы писали:
TL>>Я в Линусе чайник: что еще кроме линукса Линус написал?
MSS>7 лет назад был 15 мег зип с исходниками. Конечно, там не все один Линус писал, но он писал самые старые и фундаментальные вещи и еще и поддерживал все это как тимлид.
Т.е. Линус "удачно попав под струю" осуществил в принципе мечту каждого человека: заниматься любимым делом и не думать о деньгах. Однако же тут уже заметили, что для остальных "население планеты минус Линус" это далеко не всегда так, а чаще как раз наоборот. К тому же, как уже заметили, ничего особо нового Линус в технический прогресс не привнес — по сути своей как ни посмотри, а Линукс — явление больше социально-организационного масштаба, чем технологического.
Лично у меня нет мечты — сидеть за компьютером и писать программы. Лично я больше мечтаю об отельчике на берегу моря. Лично мне что удачливый Линус, что удачливый Гейтс, что иже с ними Стив и Стив — все это примеры удачливых людей — а сколько было неудачливых?
Лично я пока что не вижу чем Сам Линус может мне помочь в моей лично скромной жизни. Копаться в ядре линукса я не буду — что лично мне Линус еще может предложить? А полезного лично для меня?
Голь на выдумку хитра, однако...
Re[14]: Ты просто неверно понимаешь концепцию константности
Здравствуйте, Erop, Вы писали:
Pzz>>В буквальном C++'ном понимании его константность заключается в том, что я не смогу поменать указатель s. Но мне ничего не помешает пописать в память, на которую ссылается этот указатель. Изменится при этом значение объекта или нет?
E>Ты просто плохо понимаешь концепцию константности в С++. E>AFAIK, в C++ всё устроено как-то так
Я очень хорошо понимаю. Проблема как раз в том, что в C++ нет явного способа, поддерживаемого синтаксисом языка, выразить, что именно является значением объекта. А рассуждения о константности имеют смысл только как о переменной, значение которой нельзя менять.
Заметим в скобках, что в языках, в которых нет переменных (т.е., чистая функциональщина), и понятие константы не имеет смысла. В такого рода языках выражение let x = 5 не создает переменной x, а создает человеческое имя для значения 5.
Здравствуйте, Pzz, Вы писали:
Pzz>Это заблуждение. C++ в первую очередь рассчитан на индустриальный стиль программирования — когда главный индус описывает интерфейсы, а подчиненные индусы наращивают мясо на эти интерфейсы. Это не обеспечивает эффективности разработки, это обеспечивает массштабируемость (больше индусов — больше кода, почти в линейной пропорции, до тех пор, пока bandwidth главного индуса не исчерпан. А потом — кирдык).
Простите, а как разрабатывается линукс? Все дружно пишут кто что хочет, а потом Линус пытается найти из всего этого что-нибудь полезного и интегрировать в систему?
Вообще-то "индустриальный стиль программирования" применим для любого языка, способного реализовать систему из отдельных модулей, объединенных интерфейсами. Или описание функций — это не есть "описать интерфейсы"?
ЗЫ: Линус — не индус. Значит Си хороший, а Си++ — плохой. Имхо, логично.
Здравствуйте, Roman Odaisky, Вы писали:
RO>std::vector<int> const someIntegers(42u, 42);
RO>там наверняка внутри три указателя — начало данных, конец данных, конец выделенной области памяти. Как ты этот вектор ни используй, данные ты не изменишь. Спрятано всё.
Это все перестает работать, как только мы попытаемся засунуть в вектор объект, которому не все равно, где лежать.
Pzz>>Проблема в том, что в C++ управление памятью — ручное. Как его не оборачивай в темплейтные обертки, компилятор все равно не в курсе, что происходит с памятью. А без этого, видимо, высокоуровневый язык не построишь.
RO>Открою секрет: в C++09 изо всех сил стараются добавить GC. Ручное управление памятью — не проблема.
C++ вообще, как хороший наркотик. Чем больше колешься, тем больше хочется.
Pzz>>На C++, на самом деле, тоже толком никак. Например потому, что конструктор не знает, конструирует ли он константный или mutable объект.
RO>Это лишено смысла… X const x = X(); — здесь какой объект конструируется?
Отнюдь нет. Конструируя константный объект, можно было бы не заботиться о конструировании тех его запчастей, которые нужны только для неконстантного объекта. Если бы об этом можно было узнать в момент конструирования...
Здравствуйте, The Lex, Вы писали:
TL>Простите, а как разрабатывается линукс? Все дружно пишут кто что хочет, а потом Линус пытается найти из всего этого что-нибудь полезного и интегрировать в систему?
Ну примерно. К линусу приходят разные люди с идеями, "я вот тута сделал кульную штуку, давай включим ее в ядро". Линус либо включает, либо не включает. Иногда даже объясняет, почему он принимает то или иное решение
TL>Вообще-то "индустриальный стиль программирования" применим для любого языка, способного реализовать систему из отдельных модулей, объединенных интерфейсами. Или описание функций — это не есть "описать интерфейсы"?
C++ дает дополнительную гибкость именно в описании интерфейсов. В остальном он примерно такой же, как Си.
RO>>Это лишено смысла… X const x = X(); — здесь какой объект конструируется?
Pzz>Отнюдь нет. Конструируя константный объект, можно было бы не заботиться о конструировании тех его запчастей, которые нужны только для неконстантного объекта. Если бы об этом можно было узнать в момент конструирования...
В такой ситуации имхо логичнее просто сделать 2 различных типа:
class X_const {};
class X {};
Логичнее даже наверное так:
class X_const {};
class X : public X_const {};
Так проще, и в противном случае не удасться полность избавиться от издержек, т.к. раскладку объекта менять не получится.
Pzz wrote: > > Это заблуждение. C++ в первую очередь рассчитан на индустриальный стиль > программирования — когда главный индус описывает интерфейсы, а > подчиненные индусы наращивают мясо на эти интерфейсы. Это не > обеспечивает эффективности разработки, это обеспечивает > массштабируемость (больше индусов — больше кода, почти в линейной > пропорции, до тех пор, пока bandwidth главного индуса не исчерпан. А > потом — кирдык).
Ну, тогда мы явно заблуждаемся вместе. Что такое "индустриальный"
стиль программирования, как не эффективность на этапе разработки?
Принцип — разработать продукт с удовлетворительным качеством в заданные
сроки, использовав заданные ресурсы. Как правило ресурсы приоритетнее.
Да и вы приводите пример повышения именно такой эффективности —
сокращение времени, потраченного на разработку, за счет
распараллеливания задач и возможность использования множества легко
доступных посредственных программистов. А таланты архитектора — не
принадлежность языка или какой-то парадигмы. Хотя вполне могут
ограничиваться ими.
Здравствуйте, Roman Odaisky, Вы писали:
RO>Это лишено смысла… X const x = X(); — здесь какой объект конструируется?
Вообще-то тут конструируется два объекта, один временный и один константный. При этом компилятор может оптимизировать это дело и строить сразу константный.
В целом не понятно что мешает как-то предоставить доступ к информации о том, какой объект конструируется, временный, константный, на стеке или в куче. Правда не понятно зачем это так уж сильно надо. Разве что для какой-то хитрой оптимизации...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Pzz, Вы писали:
Pzz>Не насколько не распостранена. Но факт передачи указателя явно виден в точке вызова. Т.е., когда Вы читаете вызов функции, Вам не надо заглядывать в другой файл, чтобы понять, что на самом деле получит эта функция — значение или ссылку.
Ну если программу пишут нормально, то от константных ссылок указатели не берут, и уж тем более не прихранивают.
Вот смотри. функция1
одинаково неправильные...
Чем тут мешает именно ссылка? Это всего лишь оптимизация передачи значения объекта в функцию. Зачем про эту оптимизацию знать в точке вызова?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
TL>В настоящее время лишь около двух процентов системного ядра «Linux» написано самим Торвальдсом, но за ним остаётся решение о внесении изменений в официальную ветку ядра.
TL>Это и есть "очень большой и серьезный проект"?
Ну там написано, что он этим проектом руководит...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, The Lex, Вы писали:
TL>Лично я пока что не вижу чем Сам Линус может мне помочь в моей лично скромной жизни. Копаться в ядре линукса я не буду — что лично мне Линус еще может предложить? А полезного лично для меня?
Ну он начал и до какой-то степени довёл довольно сложный проект и как архитектор и как программист и как администратор и как тимлидер. Это очень большой и однозначно успешный практически опыт.
Вот поэтому к его рассуждениям и имеет смысл прислушиваться. Ну чисто чтобы на чужом опыте учиться...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[15]: Ты просто неверно понимаешь концепцию константности
Здравствуйте, Pzz, Вы писали:
Pzz>Я очень хорошо понимаю. Проблема как раз в том, что в C++ нет явного способа, поддерживаемого синтаксисом языка, выразить, что именно является значением объекта. А рассуждения о константности имеют смысл только как о переменной, значение которой нельзя менять.
Ну почему же нет? Именно описывая методы объекта ты очень точно задаёшь семантику константности...
Pzz>Заметим в скобках, что в языках, в которых нет переменных (т.е., чистая функциональщина), и понятие константы не имеет смысла. В такого рода языках выражение let x = 5 не создает переменной x, а создает человеческое имя для значения 5.
Ну это к обсуждению C vs C++ IMHO мало отношения имеет
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Maxim S. Shatskih, Вы писали:
C>>Нет. Ссылки, особенно константные ссылки, — это способ самодокументации кода. Если метод принимает константную ссылку — вызывающий может быть уверен, что метод не будет менять объект по этой ссылке (в разумном коде, естественно). MSS>Не согласен. Чем плохо const T* ?
А оно может быть NULL'ом? А можно ли его сохранить в поле класса? А какое у него время жизни?
Ты не можешь ответить на все эти вопросы просто из описания функции — нужно делать дополнительные комментарии. А это уже само по себе плохо.
C>>Многие ядерные разработчики вообще не понимают смысла константности — типа "и без const'а же работает". Вот сравнительно свежий пример: http://thread.gmane.org/gmane.linux.kernel/595956/focus=596197 MSS>Понимаете, ядерные разработчики не только ядро знают зачастую я знаю, что const — это хорошо. MSS>Но я не виноват, что Катлер с Луковским его невзлюбили и сделали все ядерные (и половину Win32шных) АПИ без него (кажется, Линус его тоже не любит).
Линус к const равнодушен, в основном из-за того, что во время изначального создания ядра семантика const еще не была нормально определена в С.
MSS>В итоге, чтобы не морочиться с кастами, приходится это "отсутствие const" волочь за собой везде и всюду.
Это, действительно, одна из причин не использовать const. Но ни в коем случае не критика в его адрес.
Здравствуйте, Maxim S. Shatskih, Вы писали:
C>>Лучше. Константные ссылки — это по сути оптимизация передачи по значению. В частности, очень частно это делается при передаче временных объектов. Если же брать на них указатель — то мы не можем знать сохранит ли вызываемый код где-то у себя. В случае со ссылками мы знаем, что вызываемый код не будет сохранять переданое ему значение (ну если его не идиоты пишут, конечно). MSS>Вот про идиотов хорошая оговорка. Идиоты могут передать ссылку в конструктор какого-то класса и позвать его через new.
Так обычно это нормально — я в своих проектах пишу, что передача const-ссылки в конструктор всегда безопасна, так как конструктор обязан будет сохранять копию объекта в поле своего класса. Введут еще rvalue reference и move semantics — вообще круто тогда будет.
MSS>Можно в комментарии к функции оговорить время жизни объекта, и имеет ли право функция сохранять данный указатель где-то.
Это опять текстовая документация, которую надо отдельно смотреть и которую можно забыть обновить.
Здравствуйте, Pzz, Вы писали:
C>>Можешь явно написать чем она плохая? Pzz>Тем, что я передаю вызываемой процедуре больше, чем хочу передать. А именно, право не просто узнать значение объекта, а еще и адрес, по которому это значение лежит.
А какие у тебя варианты еще? При передаче указателя — ты сразу передаешь адрес, а при передаче по значению — ты точно так же можешь взять адрес на временный объект.
Не вижу недостатка.
Pzz>В буквальном C++'ном понимании его константность заключается в том, что я не смогу поменать указатель s. Но мне ничего не помешает пописать в память, на которую ссылается этот указатель. Изменится при этом значение объекта или нет? Формально — нет, ведь объект лишь содержит указатель, а он не поменялся. Однако если я в силу своего высокоуровнего абстрактного понимания считаю значением объекта именно содержание строки, на которую он ссылается, значение очевидно поменялось. При этом у меня нет синтаксического способа объяснить компилятору эту тонкую семантическую грань — разве что в комментарии написать, и надеяться, что кто-то (не компилятор!) его прочтет.
Тут Егор уже объяснил. Могу объяснить и я, если интересно.
Здравствуйте, Cyberax, Вы писали:
C>Линус к const равнодушен, в основном из-за того, что во время изначального создания ядра семантика const еще не была нормально определена в С.
Семантика const в C не менялась, сколько я себя помню. Т.е., более 20-и лет. Ядро линуха появилось заметно позже. gcc поддерживал ANSI C, включая const, с очень давних времен.
Здравствуйте, Pzz, Вы писали:
C>>Линус к const равнодушен, в основном из-за того, что во время изначального создания ядра семантика const еще не была нормально определена в С. Pzz>Семантика const в C не менялась, сколько я себя помню. Т.е., более 20-и лет. Ядро линуха появилось заметно позже. gcc поддерживал ANSI C, включая const, с очень давних времен.
Здравствуйте, Cyberax, Вы писали:
Pzz>>Семантика const в C не менялась, сколько я себя помню. Т.е., более 20-и лет. Ядро линуха появилось заметно позже. gcc поддерживал ANSI C, включая const, с очень давних времен.
Здравствуйте, Cyberax, Вы писали:
Pzz>>В Си нет такой вещи, как иерархия классов. А именно ее очень болезненно переделывать. C>Как нет?!?! Очень даже есть! Посмотри на GObject'ы в GTK, например.
В Си нет такой вещи, как иерархоя классов. Ее можно при желании сделать ручками, но значительно меньше хочется, чем воспользоваться встроенной в C++. Поэтому без большой нужды делать не будешь.
GTK писали студенты, это надо понимать. Им было прикольно.
Pzz>>Сравнивать стили 2-х любых отдельно взятых человек нет смысла — индивидуальные особенности могут перевесить все особенности языка. В общем и целом, C++'ные программисты гораздо более детально описывают интерфейс (а кто так не делает — тот козел ), что приводит к раздуванию кода. Именно исходного кода, я имею ввиду. C>Эээ... Вообще-то, я лично переписывал драйвер с C-шного стиля на С++-ный — благодаря RAII код уменьшился в два раза.
Эээ. А я лично (командой из 3-х человек) выразил в 60К строк на Си примерно то, что команда из 6-и человек до меня выразила в 300К строк кода на C++. Поэтому у меня другой опыт.
P.S. Их C++'ный код был очень хорош, как и мой Сишный.
Здравствуйте, Pzz, Вы писали:
C>>А какие у тебя варианты еще? При передаче указателя — ты сразу передаешь адрес, а при передаче по значению — ты точно так же можешь взять адрес на временный объект. Pzz>Временный объект при передаче по значению — это локальная переменная вызываемой процедуры.
И что? Тут опасность в том, что возьмешь ее адрес и сохранишь его где-нибудь, где он переживет выполнение функции. С константными ссылками абсолютно точно так же.
C>>Тут Егор уже объяснил. Могу объяснить и я, если интересно. Pzz>Проще спорить с одним, чем с двумя. Выберете от себя делегата
Мне повторять лениво
Cyberax wrote: > > Здравствуйте, hexis, Вы писали: > > Не согласен абсолютно. Одним из главных принципов при разработке С++ > было: "you don't pay for what you don't use". Этот принцип вполне > нормально соблюдается почти всеми реализациями С++. В результате, на С++ > можно писать так же быстро (и даже быстрее — благодаря исключениями, > например) как и на С. Более того, можно вообще писать точно так же как и > на С (за исключением мелких различий в синтаксисе). >
Ну с этим я и не пытался спорить — конечно, на C++ можно разрабатывать
столь-же эффективные программы, что и на C. И часто — гораздо быстрее,
чем на C и с меньшим количеством ошибок. Но вы забываете, что у этого
принципа есть и обратная сторона — you pay for what you use. И цена эта
— разная, но в каждой фиче она присутствует (there is no free lunch).
Например, использование виртуальных функций в C++ — повсеместная
практика. А в C — редкость. Использование таблиц виртуальных функций в C
я не разу не встречал. А в C++ — это типичная реализация. Цена —
дополнительный уровень разименования указателя при обращении к функции.
Активное использование шаблонов в некоторых случаях улучшает
производительность, и, как правило, приводит к увеличению объема кода.
У исключений тоже есть своя цена. Попробуйте скомпилировать следующую
программу в ассемблер любимым компилятором с включенной поддержкой
исключений и с выключенной и сравните результаты:
class A
{
public:
A();
~A();
};
void funcb(A *);
void func()
{
A a;
funcb(&a);
}
И так далее. Конечно, на C++ можно писать так-же как на C. На практике
это проделывается редко. Можно в C писать как на C++, что тоже делается
редко. Насколько я понимаю, Линус говорит о том, что C делает эту цену
явной — программисту придется самостоятельно написать весь этот код. В
то время, как в C++, за кажущейся простотой исходного текста, порой
прячется очень много машинного кода — цена становится неявной, и нужно
очень хорошо знать реализацию, чтобы оптимизировать производительность и
размер кода.
Cyberax wrote: > > > H>Например, использование виртуальных функций в C++ — повсеместная > H>практика. А в C — редкость. > В нормальном коде на С++ — они используются только для классов, которые > реально могут быть полиморфными.
Конечно. Но вот насчет "реально могут быть" — я бы так не сказал. Это
зависит от проектировщика, от его опыта, и его видения задачи.
> > H>Использование таблиц виртуальных функций в C я не разу не встречал. > В С — это повседневная практика. Для GTK смотри GObject, для Линукса — > тот же интерфейс модулей или VFS и т.п.
Да, пожалуй про это я забыл. Хотя я бы не сказал, что это — повседневная
практика в C. Зато в C++ создание интерфейсов действительно повседневная
практика. Причем часто это делается не из существующих потребностей, а
из соображений возможных будущих расширений.
> > H>Активное использование шаблонов в некоторых случаях улучшает > H>производительность, и, как правило, приводит к увеличению объема кода. > Объем кода — это фигня, в разумных пределах.
Но тем не менее все это — цена, которую приходится платить. И она не
равна нулю. Понятно, что в некоторых условиях получаемый выигрыш
существенно перевешивает затраты.
> > Для табличной обработки исключений — цена будет равна *нулю* на путях, > которые не бросают исключения. Благодаря этому, программы, которые > используют исключения для обозначения ошибок, могут работать *быстрее* > программ с тупой проверкой кодов возврата. Не веришь?
Я же написал о другом — об объеме требуемого машинного кода. В
приведенном примере компилятор не знает, может ли funcb генерировать
исключения, поэтому обязан всегда обрабатывать исключения чтобы
корректно отработал деструктор. Насчет скорости — да, могут. Не всегда,
конечно, но могут. Тем не менее — оптимизация производительности не
единственный и далеко не универсальный критерий разработки.
Здравствуйте, hexis, Вы писали:
H>Конечно. Но вот насчет "реально могут быть" — я бы так не сказал. Это H>зависит от проектировщика, от его опыта, и его видения задачи.
При чем тут видение? Нет необходимости делать методы виртуальными просто так.
H>Да, пожалуй про это я забыл. Хотя я бы не сказал, что это — повседневная H>практика в C. Зато в C++ создание интерфейсов действительно повседневная H>практика. Причем часто это делается не из существующих потребностей, а H>из соображений возможных будущих расширений.
Если делается "просто так" — то пинать таких программистов ногами. Если же расширения будут — то и в С придется делать виртуальные интерфейсы.
H>Но тем не менее все это — цена, которую приходится платить. И она не H>равна нулю. Понятно, что в некоторых условиях получаемый выигрыш H>существенно перевешивает затраты.
Так ведь в чистом С затраты будут тоже, и зачастую ну точно такие же, как и в С++.
H>Я же написал о другом — об объеме требуемого машинного кода. В H>приведенном примере компилятор не знает, может ли funcb генерировать H>исключения, поэтому обязан всегда обрабатывать исключения чтобы H>корректно отработал деструктор.
Нет. Тебе стоит узнать как работают исключения. Ладно, делаем тест:
test.cpp:
#include <stdio.h>
int somefunc();
class A
{
public:
A() {printf("Cons\n");}
~A() {printf("~Cons\n");}
};
int main()
{
try
{
A obj;
somefunc();
} catch(...)
{
printf("Excpt!\n");
}
return 0;
}
Работает все правильно. Теперь начнем разбирать на кусочки:
devsrv% g++ -S test.cpp func.cpp
Вот дизассемблированая функция main():
; Обычный пролог функции
main:
.LFB8:
pushq %rbp
.LCFI6:
movq %rsp, %rbp
.LCFI7:
pushq %rbx
; Конструкция объекта
.LCFI8:
subq $24, %rsp
.LCFI9:
leaq -9(%rbp), %rdi
.LEHB0:
call _ZN1AC1Ev ; Вызов конструктора (1)
.LEHE0:
.LEHB1:
call _Z8somefuncv ; Вызов функции (2)
.LEHE1:
leaq -9(%rbp), %rdi ; Загрузка адреса объекта (3)
.LEHB2:
call _ZN1AD1Ev ; Вызов деструктора (4)
.LEHE2:
jmp .L9 ; Переход на конец функции (с оператором "return 0") (5); ОБРАБОТКА ИСКЛЮЧЕНИЙ
.L15:
movq %rax, -32(%rbp)
.L8:
movq -32(%rbp), %rbx
leaq -9(%rbp), %rdi
call _ZN1AD1Ev ; Вызов деструктора объекта Amovq %rbx, -32(%rbp)
jmp .L10
.L16:
movq %rax, -32(%rbp)
.L10:
movq -32(%rbp), %rdi
call __cxa_begin_catch
movl $.LC2, %edi
.LEHB3:
call puts ; Вызов printf
.LEHE3:
.LEHB4:
call __cxa_end_catch
.LEHE4:
jmp .L9 ; Переход на конец функции (с оператором "return 0")
.L14:
movq %rax, -32(%rbp)
.L11:
movq -32(%rbp), %rbx
call __cxa_end_catch
movq %rbx, -32(%rbp)
movq -32(%rbp), %rdi
.LEHB5:
call _Unwind_Resume
.LEHE5:
; Реализация "return 0" и эпилога функции
.L9:
movl $0, %eax
addq $24, %rsp
popq %rbx
leave
ret
Заметь, что между (1) и (5) нет никакого кода обработки исключений. Это обычный код, который идентичен тому, который генерируется с отключеными исключениями (за исключением последнего jmp).
Такая магия делается с помощью табличной обработки исключений — в секции .gcc_except_table находятся списки адресов, при броске исключения эти списки используются для сопоставления значения указателя команд с текущим блоком и поиска нужного обработчика.
Так что у нас обработка исключений получается всегда полностью бесплатной по скорости в случае, если нет бросков. Это достигается небольшим (порядка 10-15%) увеличением объема исполняемого файла за счет таблиц.
Это из Turbo C 2.0, борландского компилятора 1988-го года выпуска. Язык, который он реализует, это даже не c89, а драфт c89. Я что-то не заметил пока никакой разницы с современным положением вещей...
Здравствуйте, Pzz, Вы писали:
C>>Ну как бы все стандартные функции работы со строками до некоторого времени принимали "char*", например.
Pzz>char * _Cdecl strchr(const char * s, int c);
Это что, поддержка const?!
Pzz>Это из Turbo C 2.0, борландского компилятора 1988-го года выпуска. Язык, который он реализует, это даже не c89, а драфт c89. Я что-то не заметил пока никакой разницы с современным положением вещей...
strchr на C как следует не сделать из-за отсутствия перегрузки.
Здравствуйте, dupamid, Вы писали:
C>>Нет. Тебе стоит узнать как работают исключения. Ладно, делаем тест: D>Это ты привел пример того, как работает обработка исключений на Linux — там используется табличный подход. Для Windows 32-бита, будет сгенерирован код для прологи и эпилога функции и он будет отличаться того, который будет без исключений. Оба подхода имеют свои плюсы и минусы. Плюс табличного подхода ты привел — почти нет дополнительного сгенерированного кода. Минус — объем таблиц, когда областей видимости, временных объектов и т.п. объем таблиц может быть огромен.
По реальным данным 10-20% оверхеда по объему. Оно все достаточно компактно получается. На Windows в GCC, кстати, можно тоже табличные исключения использовать
D>Так как каждое создание объекта и его уничтожение создает новый контекст обработки исключений. Подход с генераций кода более компактен, но всегда дает накладные расходы. Кроме того, наличие возможности исключений подавляет некоторые оптимизации компилятора (исключения создают дополнительные переходы к коде, например любая функция может не вернуться — бросить исключение), так что не весь эффект от исключений выражен в новом коде или таблицах.
Ну и что, что функция может не вернуться? В этом случае, у нас будут выполнена размотка стека, и все будет нормально обработано. Если же делается inline — то у компилятора есть все данные о местах бросания исключений, так что тоже никаких проблем.
Здравствуйте, Pzz, Вы писали:
Pzz>Эээ. А я лично (командой из 3-х человек) выразил в 60К строк на Си примерно то, что команда из 6-и человек до меня выразила в 300К строк кода на C++. Поэтому у меня другой опыт.
Pzz>P.S. Их C++'ный код был очень хорош, как и мой Сишный.
Если твой код на C хорош (например, кастит результаты malloc), то он с тем же успехом представляет из себя хороший код на C++.
Здравствуйте, Cyberax, Вы писали:
C>Здравствуйте, jazzer, Вы писали:
J>>Ну т.е. Торвальдс — это менеджер. Чего он полез с менеджерской колокольни судить о языке, которого он не знает — не очень понятно. C>Нет, Торвальдс — очень хороший программист. Но! Он системный программист, часто работающий на уровне ассемблера (он писал, что GDB в качестве дизассемблера чаще всего использует).
C>В результате — у него стандартная болезнь системщиков. Т.е. неприятие чего-либо кроме С.
Здравствуйте, Cyberax, Вы писали:
C>>>Нет. Тебе стоит узнать как работают исключения. Ладно, делаем тест: D>>Это ты привел пример того, как работает обработка исключений на Linux — там используется табличный подход. Для Windows 32-бита, будет сгенерирован код для прологи и эпилога функции и он будет отличаться того, который будет без исключений. Оба подхода имеют свои плюсы и минусы. Плюс табличного подхода ты привел — почти нет дополнительного сгенерированного кода. Минус — объем таблиц, когда областей видимости, временных объектов и т.п. объем таблиц может быть огромен. C>По реальным данным 10-20% оверхеда по объему. Оно все достаточно компактно получается. На Windows в GCC, кстати, можно тоже табличные исключения использовать
Я видел реальные программы, которые распухали почти в два раза Так что это очень индивидуально и зависит от того сколько объектов создатеся и разрушается, включая все локальный, временые переменные и временные переменные создающиеся под условием типа "some_cond ? A() : f(B())", здесь будет созадана или временная переменная типа A или B и в конце вычисления полного выражения так переменная которая была созданна должна быть разрешена. Такого рода вещи создают очень много EH контекстов.
D>>Так как каждое создание объекта и его уничтожение создает новый контекст обработки исключений. Подход с генераций кода более компактен, но всегда дает накладные расходы. Кроме того, наличие возможности исключений подавляет некоторые оптимизации компилятора (исключения создают дополнительные переходы к коде, например любая функция может не вернуться — бросить исключение), так что не весь эффект от исключений выражен в новом коде или таблицах. C>Ну и что, что функция может не вернуться? В этом случае, у нас будут выполнена размотка стека, и все будет нормально обработано. Если же делается inline — то у компилятора есть все данные о местах бросания исключений, так что тоже никаких проблем.
Разница может быть в том, что компилятор будет учитывать дополнительный переход от места вызова к выходу из функции на графе потока управления (CFG) функции. Пример когда это может иметь значение, статическая переменная была поднята в регистр, значит перед вызовом функции ее предется опустить обратно в пямять (хотя может быть известно что внутри функции она не используется), так как функция может не вернуться. Кроме того в С++ намного больше вызово функций чем в обычном коде на С++ — это просто статистика. Исключения в стиле С setjmp/longjmp еще хуже в этом смысле, но они реже используются в коде на С, чем исключения в коде на С++.
Здравствуйте, Roman Odaisky, Вы писали:
RO>Нет, именно над микросхемой. У нее есть некое ограниченное, и не такое уж и большое, количество циклов чтения-записи (а точнее, стирания) на каждую ячейку. FAT использует пространство очень неравномерно, соответственно, когда она протрет дыру в начале раздела, где хранится собственно таблица, наступит виндекапец. Юниксукапец наступит значительно позже, потому что там есть JFFS2, специально созданная для флеш-памяти. Это особенно важно для новомодных безвинчестерных устройств вроде Asus Eee, где сама ОС живет на флешке. (NTFS/ext3/reiserfs ситуацию не исправят, потому что тоже рассчитаны на винчестеры.)
В принципе, с протиранием дырок на флешке можно бороться не в файловой системе, а на уровне драйвера блочного устройства. Или даже вовсе запихнуть эту логику в контроллер, который делает из флешки иллюзию IDE-диска. Тем более, что какой-то интеллект на этом уровне все равно нужен, т.к. типичный размер "сектора" (минимального куска, который можно стереть и переписать за раз) на флешке — 8-16 килобайт, а традиционные файловые системы рассчитаны на 512-байтный сектор.
Я удивляюсь, неужели в реальности этого не было сделано?
Здравствуйте, Cyberax, Вы писали:
Pzz>>Эээ. А я лично (командой из 3-х человек) выразил в 60К строк на Си примерно то, что команда из 6-и человек до меня выразила в 300К строк кода на C++. Поэтому у меня другой опыт. C>Интересно, за счет чего? За счет оптимизации алгоритмов/структуры? Мы получили выигрыш просто за счет изменения стиля кода.
Отчасти за счет того, что в C++'ном коде были очень дотошно расписаны правила игры в терминах интерфейсов — в Си так не сделаешь, поэтому и сделано не было. Отчасти же за счет того, что C++'ный код был более абстрактным и заточенным на дальнейшее развитие в неизвестно какую сторону, а Сишный был более сконцентрирован на решении практической задачи.
Любопытно при этом, что хотя C++'ный код был сознательно спроектирован гибким, реально гнуть быстрее получалось Сишный код, в силу его обозримости и относительной простоты.
А причиной переписывания, между прочим, было то, что с размахом написанный C++'ный код оказалось очень трудно перенести из той среды, для которой он изначально предназначался (железка) в драйвер для линуха и вендов — никто не подумал о том, что в драйвере стек очень маленький, и слишком много говна заводилось прямо на стеке, по всему коду. Вычистить это из 300К строк кода оказалось неподъемной задачей. Ну и плюс к тому, в вендовом NDIS'овском драйвере нет честного способа организовать ядерный поток (WHQL на NDIS'овские драйвера прямо проверяет, что Вы этого не делаете).
Здравствуйте, remark, Вы писали:
D>>Так что это очень индивидуально и зависит от того сколько объектов создатеся и разрушается, включая все локальный, временые переменные и временные переменные создающиеся под условием типа "some_cond ? A() : f(B())", здесь будет созадана или временная переменная типа A или B и в конце вычисления полного выражения так переменная которая была созданна должна быть разрешена. Такого рода вещи создают очень много EH контекстов.
R>EH контекстов (фреймов) такие вещи обычно не создают. EH фрейм обычно создаётся один на функцию. Все создания объектов с деструкторами (в т.ч. "some_cond ? A() : f(B())") просто инкрементируют неявный счётчик — некий аналог счётчика команд IP. По значению этого счётчика обработчик исключения (в т.ч. неявный, который генерируется компилятором и рушит объекты) может точно сказать какие объекты сейчас живы на стеке (т.е. какие надо разрушить).
Я был не совсем точен, я не имел в виду EH frame. Я понимал под EH контекстом уникальную область, которой соответствует уникальный набор объектов, которые нужно разрушить, если возникнет исключение в данной точке. Вот маленький пример, безусловно искуственный
class A {
public:
A(int i);
~A();
};
void goo();
void foo() {
A a1(1); A a2(2); A a3(3);
goo();
A a4(4); A a5(5); A a6(6);
}
-fno-exceptions:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 1] .text PROGBITS 00000000 000034 0000c1 00 AX 0 0 4
-fexceptions:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 1] .text PROGBITS 00000000 000034 000147 00 AX 0 0 4
[ 5] .gcc_except_table PROGBITS 00000000 00017c 000043 00 A 0 0 1
[ 6] .eh_frame PROGBITS 00000000 0001c0 00003c 00 A 0 0 4
0001c6
Здравствуйте, Pzz, Вы писали:
RO>>Нет, именно над микросхемой. У нее есть некое ограниченное, и не такое уж и большое, количество циклов чтения-записи (а точнее, стирания) на каждую ячейку. FAT использует пространство очень неравномерно, соответственно, когда она протрет дыру в начале раздела, где хранится собственно таблица, наступит виндекапец. Юниксукапец наступит значительно позже, потому что там есть JFFS2, специально созданная для флеш-памяти. Это особенно важно для новомодных безвинчестерных устройств вроде Asus Eee, где сама ОС живет на флешке. (NTFS/ext3/reiserfs ситуацию не исправят, потому что тоже рассчитаны на винчестеры.)
Pzz>В принципе, с протиранием дырок на флешке можно бороться не в файловой системе, а на уровне драйвера блочного устройства. Или даже вовсе запихнуть эту логику в контроллер, который делает из флешки иллюзию IDE-диска. Тем более, что какой-то интеллект на этом уровне все равно нужен, т.к. типичный размер "сектора" (минимального куска, который можно стереть и переписать за раз) на флешке — 8-16 килобайт, а традиционные файловые системы рассчитаны на 512-байтный сектор.
На флешке проблематична операция «прочесть байт, увеличить на 1, записать обратно». Потому традиционные файловые системы мало подходят. JFFS2 же дописывает изменения на свободное место, а при необходимости делает GC, чем уменьшает количество стираний и распределяет их равномерно по флешке.
Это и есть дело ФС, а не драйвера. Если ext3 постоянно меняет номер inode или, чего доброго, отслеживает atime, никакой драйвер это не соптимизирует.
Cyberax wrote: > > > H>Конечно. Но вот насчет "реально могут быть" — я бы так не сказал. Это > H>зависит от проектировщика, от его опыта, и его видения задачи. > При чем тут видение? Нет необходимости делать методы виртуальными просто > так.
Что значит — "просто так"? Когда я пишу программы, я всегда предполагаю,
куда и как она будет развиваться в дальнейшем. Исходя из этих
соображений я могу использовать интерфейс там, даже если на первом этапе
будет всего лишь одна его реализация. И не считаю это плохой практикой.
> > H>Но тем не менее все это — цена, которую приходится платить. И она не > H>равна нулю. Понятно, что в некоторых условиях получаемый выигрыш > H>существенно перевешивает затраты. > Так ведь в чистом С затраты будут тоже, и зачастую ну точно такие же, > как и в С++.
Ну кто-же спорит? Конечно будут. Я еще раз повторяю — C обычно
заставляет программистов использовать другие парадигмы, нежели C++.
Программы на C обычно более специализированны под конкретную область,
что делает их более эффективными, но создает сложности при попытке
расширения и модификации программы. Особенно, если требуется заменить
некоторое проектное решение.
Кроме того, если еще такая вещь, как инертность мышления. Когда
концентрируешься на определенных парадигмах решения задач, многие
последовательные решения выполняются в едином стиле, несмотря на то, что
некоторые из них было бы эффективнее выполнить в другом.
> > H>Я же написал о другом — об объеме требуемого машинного кода. В > H>приведенном примере компилятор не знает, может ли funcb генерировать > H>исключения, поэтому обязан всегда обрабатывать исключения чтобы > H>корректно отработал деструктор. > Нет. Тебе стоит узнать как работают исключения. Ладно, делаем тест:
Ну что-же, не буду врать, не знал, что gcc умеет отслеживает контекст
исполнения по адресу, а не по счетчику. Но тем не менее, исключения так
работают далеко не всегда. Хочешь приведу то, что генерирует тот-же
mingw-gcc 3.4.2, который использует sjlj обработку исключений? Или
поверишь на слово, что есть разница?
D>Я был не совсем точен, я не имел в виду EH frame. Я понимал под EH контекстом уникальную область, которой соответствует уникальный набор объектов, которые нужно разрушить, если возникнет исключение в данной точке.
Для поддержания этого EH контекста достаточно просто инкрементировать переменную. При этом если производится ручное управление ресурсами, то в общем случае надо вручную поддерживать эту же переменную.
D>Вот маленький пример, безусловно искуственный
Это две разные программы, имеющие разную семантику. Очевидно, что они будут иметь разный размер.
Здравствуйте, Roman Odaisky, Вы писали:
RO>На флешке проблематична операция «прочесть байт, увеличить на 1, записать обратно». Потому традиционные файловые системы мало подходят. JFFS2 же дописывает изменения на свободное место, а при необходимости делает GC, чем уменьшает количество стираний и распределяет их равномерно по флешке.
За описание принципов работы jffs2 спасибо, но я как-бы в курсе.
Представьте себе, что мы берем jffs2 и используем ее следующим образом: создаем файлы с именами от 0 до N, каждый файл — 512 байт. Представили? Теперь представьте себе, что мы делаем block device, который каждый 512-байтный сектор хранит в отдельном таком файле. А теперь выкинем из этой конструкции все лишнее — имена файлов, например.
В итоге мы получили блочный девайс, на котором можно держать не предназначенную для флешки файловую систему, и при этом она не будет протирать дырки во флешке, или мучаться из-за неподходящего размера блока.
Мне как-то всегда казалось, что когда из флешки делают IDE disk, то это делают каким-то примерно таким образом. В противном случае я не понимаю, они что, ради каждого записанного байта трут весь 8-килобайтный сектор? Как-то слабо верится...
Здравствуйте, remark, Вы писали:
D>>Я был не совсем точен, я не имел в виду EH frame. Я понимал под EH контекстом уникальную область, которой соответствует уникальный набор объектов, которые нужно разрушить, если возникнет исключение в данной точке. R>Для поддержания этого EH контекста достаточно просто инкрементировать переменную. При этом если производится ручное управление ресурсами, то в общем случае надо вручную поддерживать эту же переменную.
Как тут уже много говорили есть схемы основанные на табличной обработке исключения, она используется обычно на Linux. Для нее нет нужды инкриментировать ничего. По IP адресу точки вызова вычисляется контекст и адрес обработчика для раскрутки стека. Инкримент, про который ты пишешь, может быть достаточно дорог, это как минимум еще одна дополнительная переменная, для X86 с малым числом регистров это может быть весьма существенно — появление spill/fill для этой переменной, кроме того между вызовами она обязана быть на стеке, чтобы ее мог достать обработчик проводящий раскрутку стека. Сказать что табличный подход или подход со счетчиками лучше однозначно нельзя — это зависит от множества факторов.
D>>Вот маленький пример, безусловно искуственный R>Это две разные программы, имеющие разную семантику. Очевидно, что они будут иметь разный размер.
Когда компилятор компилирует этот модуль у него нет возможности узнать что поддержка для обработки исключений тут может быть не нужна. Единственная возможность узнать это компилятору — это ключ пользователя. Семантика это наблюдаемое поведение программы, есть множество программ, для которых семантика программы не меняется от включения или выключения опции поддержки исключений.
Здравствуйте, dupamid, Вы писали:
D>Здравствуйте, remark, Вы писали:
D>>>Я был не совсем точен, я не имел в виду EH frame. Я понимал под EH контекстом уникальную область, которой соответствует уникальный набор объектов, которые нужно разрушить, если возникнет исключение в данной точке. R>>Для поддержания этого EH контекста достаточно просто инкрементировать переменную. При этом если производится ручное управление ресурсами, то в общем случае надо вручную поддерживать эту же переменную.
D>Как тут уже много говорили есть схемы основанные на табличной обработке исключения, она используется обычно на Linux. Для нее нет нужды инкриментировать ничего. По IP адресу точки вызова вычисляется контекст и адрес обработчика для раскрутки стека.
Ты сам сказал про создание контекстов в ран-тайм, поэтому я подумал, что мы говорим про студию
D>Инкримент, про который ты пишешь, может быть достаточно дорог, это как минимум еще одна дополнительная переменная, для X86 с малым числом регистров это может быть весьма существенно — появление spill/fill для этой переменной, кроме того между вызовами она обязана быть на стеке, чтобы ее мог достать обработчик проводящий раскрутку стека.
Она не становится дороже от того, что её создаёт коспилятор, чем если бы её создал программист.
D>Сказать что табличный подход или подход со счетчиками лучше однозначно нельзя — это зависит от множества факторов.
D>>>Вот маленький пример, безусловно искуственный R>>Это две разные программы, имеющие разную семантику. Очевидно, что они будут иметь разный размер.
D>Когда компилятор компилирует этот модуль у него нет возможности узнать что поддержка для обработки исключений тут может быть не нужна. Единственная возможность узнать это компилятору — это ключ пользователя. Семантика это наблюдаемое поведение программы, есть множество программ, для которых семантика программы не меняется от включения или выключения опции поддержки исключений.
Т.е. ты имеешь в виду случай, когда в программе используются деструкторы, но при этом не кидаются исключения, и используется только new(std::nothrow) и не используется dynamic_cast для ссылок и at() для vector и т.д., и не используются никакие библиотеки, которые могут это использовать? Я не уверен, что такой случай вообще имеет смысл рассматривать... И в любом случае, я бы не назвал эти программы "множество программ"...
Здравствуйте, Pzz, Вы писали:
Pzz>Мне как-то всегда казалось, что когда из флешки делают IDE disk, то это делают каким-то примерно таким образом. В противном случае я не понимаю, они что, ради каждого записанного байта трут весь 8-килобайтный сектор? Как-то слабо верится...
Судя по ничтожной скорости создания-записи мелких файлов — таки да.
Здравствуйте, The Lex, Вы писали:
Pzz>>Мне как-то всегда казалось, что когда из флешки делают IDE disk, то это делают каким-то примерно таким образом. В противном случае я не понимаю, они что, ради каждого записанного байта трут весь 8-килобайтный сектор? Как-то слабо верится...
TL>Судя по ничтожной скорости создания-записи мелких файлов — таки да.
Куда катится мир?...
Может это только в дешевых китайских флешках так? А в более приличных — по-человечески?
J>Это где же Александреску говорил, что его решения — для прикладного программирования??? J>А если какие-то идиоты принимаются писать прикладной код в стиле библиотечного кода, а гуй — на асме, а драйвер — на вижуал-бейсике — так это их персональные половые проблемы.
Да и в "Моей Борьбе" ничего такого в целом ненаписано. Но идиоты нашлись и находятся до сих пор... Может таки не толкьо в идиотах дело?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, dupamid, Вы писали:
C>>По реальным данным 10-20% оверхеда по объему. Оно все достаточно компактно получается. На Windows в GCC, кстати, можно тоже табличные исключения использовать D>Я видел реальные программы, которые распухали почти в два раза Так что это очень индивидуально и зависит от того сколько объектов создатеся и разрушается, включая все локальный, временые переменные и временные переменные создающиеся под условием типа "some_cond ? A() : f(B())", здесь будет созадана или временная переменная типа A или B и в конце вычисления полного выражения так переменная которая была созданна должна быть разрешена. Такого рода вещи создают очень много EH контекстов.
EH-таблицы очень компактны — это просто, фактически, указания какие диапазоны указателя инструкций (eip/rip/...) соответствуют каким объектам.
Может, конечно, в вырожденных случаях и будет все плохо — но на KDE я полчал порядка 15% уменьшения объема кода при отключении исключений.
D>Разница может быть в том, что компилятор будет учитывать дополнительный переход от места вызова к выходу из функции на графе потока управления (CFG) функции. Пример когда это может иметь значение, статическая переменная была поднята в регистр, значит перед вызовом функции ее предется опустить обратно в пямять (хотя может быть известно что внутри функции она не используется), так как функция может не вернуться.
AFAIR, при вызове функций и так придется закоммитить переменные в память — так как мы не знаем, какие регистры затронет функция. Если же у компилятора есть доступ к телу функции, то мы можем закоммитить переменную перед местами броска исключений.
На практике, от включения исключений тормозов не заметно (кроме "эффектов второго порядка" от большего cache contention'а).
Здравствуйте, Cyberax, Вы писали:
C>Это называется синдром YAGNI (You Ain't Gonna Need It) — если бы на С проектировали в таком же стиле, то объем кода был бы в разы больше С++ То есть, это опять проблемы не языка, а разработчиков.
Если бы мне такое захотелось напрограммировать на Си, я бы придумал domain-specific language, и написал бы компилятор. Чем сократил бы объем кода в разы
В тех 60К строк компилятор, кстати, был. Но не со столь фундаментальной целью. Выплюнул он из себя примерно столько же кода, сколько весил сам вместе с исходниками на евонном языке, но писать его было гораздо веселее, чем написать руками (а тем более — поддерживать) эквиавалент автоматически сгенеренного кода.
Но в общем и целом, я свое мнение сказал выше — по любым 2-м отдельно взятым проектам сравнивать бессмысленно, т.к. влияние стиля разработчика скажется больше, чем разница между языками.
Здравствуйте, hexis, Вы писали:
H>Что значит — "просто так"? Когда я пишу программы, я всегда предполагаю, H>куда и как она будет развиваться в дальнейшем. Исходя из этих H>соображений я могу использовать интерфейс там, даже если на первом этапе H> будет всего лишь одна его реализация. И не считаю это плохой практикой.
Тогда тебе нужно будет делать то же самое и для программ на С (с помощью самодельных виртуальных таблиц). Или признать, что это плохая практика.
>> Нет. Тебе стоит узнать как работают исключения. Ладно, делаем тест: H>Ну что-же, не буду врать, не знал, что gcc умеет отслеживает контекст H>исполнения по адресу, а не по счетчику. Но тем не менее, исключения так H>работают далеко не всегда. Хочешь приведу то, что генерирует тот-же H>mingw-gcc 3.4.2, который использует sjlj обработку исключений? Или H>поверишь на слово, что есть разница?
Да я знаю, что sjlj-исключения (и их аналог — SEH) — это мастдай. Поэтому и надо нормальные компиляторы и инструменты использовать.
Здравствуйте, Pzz, Вы писали:
Pzz>В принципе, с протиранием дырок на флешке можно бороться не в файловой системе, а на уровне драйвера блочного устройства. Или даже вовсе запихнуть эту логику в контроллер, который делает из флешки иллюзию IDE-диска. Тем более, что какой-то интеллект на этом уровне все равно нужен, т.к. типичный размер "сектора" (минимального куска, который можно стереть и переписать за раз) на флешке — 8-16 килобайт, а традиционные файловые системы рассчитаны на 512-байтный сектор.
Pzz>Я удивляюсь, неужели в реальности этого не было сделано?
Сделано. Штука называется "wear leveling". Так что можете за флэшку не бояться.
Здравствуйте, Cyberax, Вы писали:
C>AFAIR, при вызове функций и так придется закоммитить переменные в память — так как мы не знаем, какие регистры затронет функция. Если же у компилятора есть доступ к телу функции, то мы можем закоммитить переменную перед местами броска исключений.
Регистры обычно разделяются на три категории: caller save, callee save и scratch. Таким образом, во время вызова функции значение можно оставить в callee save регистре, так как вызываемая функция не имеет права его испортить, если он ей будет нужен, она сама его сохранит и перед выходом восстановит.
C>На практике, от включения исключений тормозов не заметно (кроме "эффектов второго порядка" от большего cache contention'а).
А что за эффект cache contention'а при включении исключений? Можно поподробнее?
Я правильно понял, что ты говоришь о ситуации, когда мы просто отключаем исключения в программе, которая на самом деле их использует, и тем самым фактически выключаем всю обработку ошибок (по крайней мере обработку нехватки памяти)?
Здравствуйте, Cyberax, Вы писали:
C>>>На практике, от включения исключений тормозов не заметно (кроме "эффектов второго порядка" от большего cache contention'а). R>>А что за эффект cache contention'а при включении исключений? Можно поподробнее? C>Код начинает занимать больший объем, а значит появляется больше шансов, что переход или вызов функции не попадут в кэш. На практике, такие эффекты почти не заметны, хотя в вырожденных случаях можно сделать замедление в разы.
Понял.
R>>Я правильно понял, что ты говоришь о ситуации, когда мы просто отключаем исключения в программе, которая на самом деле их использует, и тем самым фактически выключаем всю обработку ошибок (по крайней мере обработку нехватки памяти)? C>Да, в качестве теста на верхнюю границу оверхеда — вполне подходит.
Но ведь это фактически сравнение 2 разных программ. Какой смысл это сравнивать? Логично сравнивать что-то сделанное одним методов против того же сделанного другим методом.
Либо тогда надо сравнивать как-то так. Замерить С код с удалёнными проверками возвращаемых значений и соотв. освобождениями ресурсов. Даже правильнее у функций сделать возвращаемое значение void. Далее замерить С код с проверками и освобождениями. И С++ код с исключениями.
Тогда можно будет сделать какое-то заключение об оверхеде исключений. А так даже не понятно что с чем сравнивать.
Кстати. Ради интереса отключил исключения и студии. Она всё равно на месте try/catch вставляет генерацию фрейма:
И исключения продолжают кидаться и ловиться. Что она перестала делать — создавать неявные фреймы для разрушения локальных объектов, и соотв. поддерживать неявный счётчик созданных объектов.
А явные try/catch — это как раз подход использующийся в контейнерах стандартной библиотеки в студии. Т.у. если используются стандартная библиотека или явные try/catch, то значительная часть оверхеда от них остаётся.
Если бы в стандартной библиотеке студии использовали RAII вместо try/catch, то она была бы генерировать более быстрый код при отключенных исключениях...
AJD>>А зачем его туда тянуть если ядру уже 100 лет в обед и оно и так работает. Когда ядро начали разрабатывать разве были нормальные компиляторы с++? MSS>Ходят сплетни, что 2мерную графику в НТ строили cfrontом ftdisk и portcls — это намного позже уже, второй особенно.
А насколько этим сплетням можно доверять? И что понимается под "2мерную графику в НТ" — GDI?
Здравствуйте, Roman Odaisky, Вы писали:
КБ>>Сделано. Штука называется "wear leveling". Так что можете за флэшку не бояться.
RO>Хм, похоже, ты более прав, чем я. Хотя я до конца так и не понял. http://en.wikipedia.org/wiki/Flash_memory#Flash_file_systems.
Есть 2 разных подхода. Флешка может быть просто припаяна к системной шине. Тогда она выглядит как флешка — большие сектора, ограниченное количество циклов перезаписи и т.п. А может изображать из себя IDE disk. Тогда она и выглядит как IDE disk — сектора по 512 байт и т.п. Первый случай — обычная практика во всяких там embedded системах. Второй — это все эти флеш-брелки, а так же новая мода, ставить флешку вместо диска в нотебуки. В первом случае уместна jffs2, во втором можно использовать традиционную файловую систему.
Я не уверен, кстати, что jffs2 хорошо себя ведет на флешках размером в несколько гигабайт. Ее, все же, не для того проектировали.
Здравствуйте, Pzz, Вы писали:
TL>>Судя по ничтожной скорости создания-записи мелких файлов — таки да.
Pzz>Может это только в дешевых китайских флешках так? А в более приличных — по-человечески?
Трудно сказать — я в своей цифрофотографии пользуюсь "почти топовыми" SanDisk Extreme III — ситуациая аналогична. Но могу согласиться что эффект обусловнен контролером и интерфейсом USB и что если подключить флешку напрямую к IDE то скорость выровняется. Однако, насколько я знаю, это таки из-за того что флешка пишется своими строками, а не секторами файловой системы.
Здравствуйте, Left2, Вы писали:
L>Добавлю от себя — ссылка закрывает арифметику указателей. Что возлагает на компилятор контроль за тем что я могу случайно (при синтаксисе С/C++ это как два байта переслать) сделать инкремент указателя (а хотел — обьекта). Оччень приятная мелочь.
Инкремент объекта? =) У вас часто встречаются объекты поддерживающие инкремент?
Здравствуйте, Константин Б., Вы писали:
КБ>Инкремент объекта? =) У вас часто встречаются объекты поддерживающие инкремент?
Присваивание -- часто...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, The Lex, Вы писали:
TL>>Лично я пока что не вижу чем Сам Линус может мне помочь в моей лично скромной жизни. Копаться в ядре линукса я не буду — что лично мне Линус еще может предложить? А полезного лично для меня?
E>Ну он начал и до какой-то степени довёл довольно сложный проект и как архитектор и как программист и как администратор и как тимлидер. Это очень большой и однозначно успешный практически опыт.
E>Вот поэтому к его рассуждениям и имеет смысл прислушиваться. Ну чисто чтобы на чужом опыте учиться...
Ты не озвучишь его опыт ведения проектов на С++?
Он ведь именно о С++ изволит говорить, а я вот не помню, чтоб он вообще на С++ серьезно писал, не говоря уже о руководстве С++-проектами.
Здравствуйте, Ka3a4oK, Вы писали:
AA>>Нет силы разрушительной страшнее, AA>>Чем кода стиль "Я-Прочитал-Александреску"...
KK>Буст не в таком ли стиле написан ?
нет
Здравствуйте, jazzer, Вы писали:
J>Ты не озвучишь его опыт ведения проектов на С++? J>Он ведь именно о С++ изволит говорить, а я вот не помню, чтоб он вообще на С++ серьезно писал, не говоря уже о руководстве С++-проектами.
Он говорит о том, чем ему не нравится С++ применительно к большому и сложному софтверному проекту. Возможно, конечно, он С++ не знает, но ты-то может быть и знаешь. Так что можешь оценить его аргументацию. Только не в стиле "он дурак, и С++ не знает", а в стиле "вот чувак имеет такие-то опасения. Что я сделаю в своём С++ проекте, чтобы его опасения не стали правдой?"
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, OCTAGRAM, Вы писали:
OCT>Чего только не приплетут, и Линус больной системщик, и менеджер, и OCT>колокольня у него уже не та. Что угодно, лишь бы не слышать OCT>нежелательную информацию.
А поконкретнее? Можно рациональные нежелательные аргументы?
Cyberax пишет:
> OCT>Чего только не приплетут, и Линус больной системщик, и менеджер, и > OCT>колокольня у него уже не та. Что угодно, лишь бы не слышать > OCT>нежелательную информацию. > А поконкретнее? Можно рациональные нежелательные аргументы?
Тема перетёрта на сто раз. Было бы желание искать, всё в нете есть.
Нужны аргументы — пожалуйста. FQA Lite, например. http://yosefk.com/c++fqa/
Нужны люди с C++ прошлым — пожалуйста. Martin Krischik, например. Далеко
не единственный.
Нужны ответы на вопросы — наверняка, вы не первый, кто их задал, и они
уже отвечены. Да и сами вопросы достаточно предсказуемы. На http://groups.google.com/group/comp.lang.ada были неплохие дискуссии
года два-три назад.
Много хорошие цитат было собрано в http://www.cs.kuleuven.ac.be/~dirk/quotes.html#PL
Здравствуйте, OCTAGRAM, Вы писали:
OCT>Тема перетёрта на сто раз. Было бы желание искать, всё в нете есть. OCT>Нужны аргументы — пожалуйста. FQA Lite, например. OCT>http://yosefk.com/c++fqa/
Это FUD Lite. Сразу наткнулся:
[11.2] What's the order that local objects are destructed?
FAQ: In reverse order of construction — the stuff declared last is destroyed first.
FQA: Which makes sense, but are you sure you want to write code that depends on this?
[11.3] What's the order that objects in an array are destructed?
FAQ: In reverse order of construction — the last element is destroyed first.
FQA: Which sort of makes sense, but you surely don't want to write code that depends on that one, do you?
Мда. И такого там еще полная куча.
Правильная критика, конечно, есть — но почему-то не приводится как это лучше делать в чистом С.
OCT>Нужны люди с C++ прошлым — пожалуйста. Martin Krischik, например. Далеко OCT>не единственный.
И?
OCT>Нужны ответы на вопросы — наверняка, вы не первый, кто их задал, и они OCT>уже отвечены. Да и сами вопросы достаточно предсказуемы.
Именно, не вопросы, а FUD со стороны С++ haters.
OCT>http://groups.google.com/group/comp.lang.ada были неплохие дискуссии OCT>года два-три назад.
Мда. Еще и ADA не хватало.
OCT>Много хорошие цитат было собрано в OCT>http://www.cs.kuleuven.ac.be/~dirk/quotes.html#PL OCT>На эту тему уже трудно сказать что-то новое.
Правильно. Нефиг FUD распространять.
dupamid пишет: > Это просто раздувание еще одной священной войны. Что касается критики > С++ то язык не без грехов, *но* во-первых часть этих грехов была > унаследована от горячо любимого Линусом С, а во-вторых реально лучших > альтернатив нет.
Ада? > и если она действительно будет так хороша люди на нее перейдут.
Наиииивный. В IT мире другие законы. Большинство равняется на
большинство, создавая положительную обратную связь. Управляется это
большинство в большей степени деньгами и маркетингом, нежели здравым
смыслом. Любая нелепость может стать обыденностью. Об алгоритмах и
программах <http://is.ifmo.ru/reflections/algorithms/> :
> Если говорить о промышленной разработке корпоративных систем, то > индустрия уже давно топчется на месте. Ситуация с постоянным выпуском > новых версий, появлением платформ и сред больше напоминает шоу-бизнес, > чем серьезную вдумчивую работу. В результате мы имеем кучу красивых > разноцветных кирпичей, из которых можно построить все что угодно, > кроме дома, для построения которого мы их собственно и покупали.
> Еще могу добавить, что подавляющее большинство критиков С++ его > банально плохо знают и не понимают почему он устроен так сложно, т.е. > критика С++ сводиться к тому, что язык слишком сложен, я его не > понимаю и не понимаю код, который пишут другие — поэтому С++ плох. > Плохой код можно писать на любом языке, так же как и хороший.
Да, но это не оправдание для тех остальных, кто C++ знает хорошо.
Здравствуйте, OCTAGRAM, Вы писали:
OCT>Ада?
В морг. Тяжелый и неудобный язык.
Софт для Шаттлов в ней писать, может и нормально, но все остальное — нафиг.
OCT>Наиииивный. В IT мире другие законы. Большинство равняется на OCT>большинство, создавая положительную обратную связь. Управляется это OCT>большинство в большей степени деньгами и маркетингом, нежели здравым OCT>смыслом. Любая нелепость может стать обыденностью.
И? Многие технологии и языки абсолютно без всякого большинства пробились. Примеры: Perl, Python, Ruby.
OCT>Да, но это не оправдание для тех остальных, кто C++ знает хорошо.
Понимаешь, есть нормальная критика С++. А есть FUD, типа Линусовского. Никто же не говорит, что С++ идеален.
Cyberax пишет: > Сразу наткнулся:
Ну так я тоже натыкался. В Defective operator overloading
<http://yosefk.com/c++fqa/defective.html#defect-9> так описано, что
можно подумать, нельзя обойтись без сборки мусора, чтобы не вернуть
результат без копирования. Понятно, что профи обычно не посвящают время
собиранию таких аргументов. > Мда. И такого там еще полная куча. OCT>Нужны люди с C++ прошлым — пожалуйста. Martin Krischik, например.
Далеко > OCT>не единственный. > И?
Ну Линуса же забраковали, надо кого–то же взамен. > OCT>Нужны ответы на вопросы — наверняка, вы не первый, кто их задал, и > они > OCT>уже отвечены. Да и сами вопросы достаточно предсказуемы. > Именно, не вопросы, а FUD со стороны С++ haters. > OCT>Много хорошие цитат было собрано в > OCT>http://www.cs.kuleuven.ac.be/~dirk/quotes.html#PL > <http://www.cs.kuleuven.ac.be/%7Edirk/quotes.html#PL> > OCT>На эту тему уже трудно сказать что-то новое. > Правильно. Нефиг FUD распространять.
Напомнило: 6. A monkey sees anything "different" as automatically
"wrong". <http://tonymarston.com/php-mysql/code-monkey.html>
Да, это очень просто так жить на свете. Что бы ни говорили плохо про C++
— всё FUD. Всё. Абсолютно. Можно даже не утруждать себя углублением в
детали. > OCT>http://groups.google.com/group/comp.lang.ada были неплохие дискуссии > OCT>года два-три назад. > Мда. Еще и ADA не хватало.
а) *Ада*. б) ну должна же для конструктивной критики быть хотя бы одна
альтернатива
Cyberax пишет: > Здравствуйте, OCTAGRAM, Вы писали: > > OCT>Ада? > В морг. Тяжелый и неудобный язык. >
А чем отличаешься ты, когда, не писав на Аде ни строчки, вдруг
заявляешь, что это «тяжёлый и неудобный» язык от Линуса в его критике
C++? Что–то мне подсказывает, Линус–то как раз имел с C++ гораздо больше
дела. > Софт для Шаттлов в ней писать, может и нормально, но все остальное — нафиг. >
Кстати, это называется стереотипами. > И? Многие технологии и языки абсолютно без всякого большинства пробились. Примеры: Perl, Python, Ruby. >
Поначалу без большинства. Поначалу нужно набрать критическую массу. Её
можно набрать честно, а можно нечестно. > OCT>Да, но это не оправдание для тех остальных, кто C++ знает хорошо. > Понимаешь, есть нормальная критика С++. А есть FUD, типа Линусовского. Никто же не говорит, что С++ идеален.
Линус и не планировал этот пост как «нормальную критику» C++ выставлять,
так что в этом плане сильно не придерёшься. Его спросили, почему, мол,
де, так–то и так–то. Не вываливать же ему трактаты при каждом случае.
Кому надо, сам узнает, откуда что растёт.
Здравствуйте, OCTAGRAM, Вы писали:
>> OCT>Ада? >> В морг. Тяжелый и неудобный язык. OCT>А чем отличаешься ты, когда, не писав на Аде ни строчки,
Страдаем телепатией?
OCT> вдруг заявляешь, что это «тяжёлый и неудобный» язык от Линуса в его критике OCT>C++? Что–то мне подсказывает, Линус–то как раз имел с C++ гораздо больше OCT>дела.
Тем не менее, его аргументы не выдерживают критики.
>> Софт для Шаттлов в ней писать, может и нормально, но все остальное — нафиг. OCT>Кстати, это называется стереотипами.
Ну так сломайте мои стереотипы — покажите хотя бы несколько мейнстримовых программ на ней. Даже на OCaml'е есть распространенный MLDonkey и darcs на Haskell'е.
>> И? Многие технологии и языки абсолютно без всякого большинства пробились. Примеры: Perl, Python, Ruby. OCT>Поначалу без большинства. Поначалу нужно набрать критическую массу. Её OCT>можно набрать честно, а можно нечестно.
Сколько лет Аде, например? Точно за 20 лет уже перевалило. Прорывов пока не видно.
OCT>Линус и не планировал этот пост как «нормальную критику» C++ выставлять, OCT>так что в этом плане сильно не придерёшься. Его спросили, почему, мол, OCT>де, так–то и так–то. Не вываливать же ему трактаты при каждом случае.
Правильно в таком случае, тогда, было бы так и сказать: "Я не могу привести простых и коротких примеров". Я уж не говорю, что есть действительно правильная критика С++, которую и без трактатов можно написать.
Cyberax пишет:
>> > OCT>Ада? >> > В морг. Тяжелый и неудобный язык. > OCT>А чем отличаешься ты, когда, не писав на Аде ни строчки, > Страдаем телепатией?
Да очень похоже на то. А что, я далеко от истины?
> Тем не менее, его аргументы не выдерживают критики.
Соглашусь.
> Ну так сломайте мои стереотипы — покажите хотя бы несколько
Стереотип в том, что Ада подходит только для шаттлов. Нет, не только.
Императивный язык общего назначения.
> мейнстримовых программ на ней. Даже на OCaml'е есть распространенный > MLDonkey и darcs на Haskell'е.
А зачем именно мейнстримных? Разве распространённость многого стоит?
Ну есть разные вещи в свободном доступе, не знаю, насколько
распространённые. От научных библиотек до линуксовых игр.
Я, если бы делал проект именно для всеобщего пользования, не стал бы
шибко трубить этом, «чтобы прям всем было видно». Для меня это обыденный
повседневный язык.
> Сколько лет Аде, например? Точно за 20 лет уже перевалило. Прорывов пока > не видно.
а) ну она же регулярно обновляется. Текущий стандарт в 2007м году был
принят.
б) что значит «прорыв»? Очередное «изобретение», что ли? Опять? Всё, что
можно изобрести, уже давно изобретено. Как правило.
Мало изобрести, ещё нужно воплотить, и сделать это можно разными
способами. При этом получается и мёд, и дёготь, если воспользоваться
этой аллегорией. «Прорывы» подразумевают много мёда. В случае Ады
прорывом можно считать мало дёгтя.
А если говорить про мёд, то в Аде есть хорошие фичи и от C++, и от C99
(кои не достались C++), и ещё свои помимо этого, и это гармонично
скомпоновано. Богатый, но не раздутый язык программирования.
Ну и возраст тоже немаловажный плюс. За такое время язык был хорошо
обкатан в самых разных проектах. Ада не модная побрякушка (FoxPro). Мода
приходит и уходит. И не экспериментальная штучка, которая выпускается
подряд версия за версией (Python, Delphi). И не результат демократии
комитета (C++).
Нет, это очень стабильный язык программирования. Программы, написанные
на этом языке, переживают десятилетия. И продолжают работать под
компиляторами новых стандартов. Параноидальной совместимости между
стандартами нет, но, как правило, менять много не приходится.
Не так уж много языков являются столь же прочным фундаментом, как Ада.
Pzz пишет:
> Я не очень в курсе, как они делят машину между mach'ем и BSD.
Положительные номера точек входа для BSD, отрицательные для Mach.
Так или иначе, делается всё через Mach. Если программа вызовом
BSD спрашивает, сколько сейчас времени, то это преобразуется в вызов
Mach «передать сообщение» серверу времени, сервер времени отвечает
сообщением на сообщение, возвращается результат.
> Там есть еще фрамеворк для писания ядреных драйверов, на C++. Часть > драйверов втыкается именно в него — например, сетевые драйвера.
Здравствуйте, Pzz, Вы писали:
Pzz>>>Неужели Ада хуже C++? C>>Определи понятие "хуже". Pzz>Тяжелей и неудобней.
Я на Ada немного писал, но мне она показалась очень уже многословной. По фичам — больше похоже на какой-нибудь Оберон, но более заточеная на безопасность.
Cyberax пишет:
C> По фичам — больше похоже на какой-нибудь Оберон
Oberon был разработан в школе Вирта. А Ичбиа и Вирт во многом друг с
другом расходились во мнениях, так что похожими их языки можно назвать
только в грубом приближении.
Здравствуйте, OCTAGRAM, Вы писали:
C>> По фичам — больше похоже на какой-нибудь Оберон OCT>Oberon был разработан в школе Вирта. А Ичбиа и Вирт во многом друг с OCT>другом расходились во мнениях, так что похожими их языки можно назвать OCT>только в грубом приближении.
Если смотреть с расстояния Haskell'а, OCaml'а или даже C# — то похожи.
Cyberax пишет:
> Здравствуйте, OCTAGRAM, Вы писали:
> Если смотреть с расстояния Haskell'а, OCaml'а
LOL оригинальный подход к изучению императивных языков
> или даже C# — то похожи.
Оберон–то как раз ближе к C#. Oberon, Java, C# все из одного семейства.
Виртуальная машина(в Обероне, по крайней мере, изначально). Отражения.
Компонентный стиль.
Здравствуйте, jazzer, Вы писали:
J>Чем тратить время на борьбу с его ветряными мельницами, я, честное слово, лучше почитаю тех, кто либо профессионал в менеджменте вообще, либо профессионал в разработке, проектировании и управлении проектами именно на С++ — потому что это будет то, что есть в реальности, а не то, что кому-то с его далекой колокольни кажется.
Флеймя на форуме ты конечно много времени экономишь...
Эх, мне бы так научиться
А если конкретно, то позиция простая. У С-программистов более удачная по его мнению система ценностей.
Из этого он делает вывод, что С++ порочен. так как воспитывает специалистов с неправильной, по его мнению, системой ценностей
ИМХО в этом он не прав. Если таки вооружиться С-шной системой ценностей и прогать на С++, будет ещё лучше.
Другое дело, что этот великолепный план упрётся в две практические трудности
1) Будет трудно найти программистов, которые разделяют такую систему ценностей, но знают С++
2) Хорошо знать С намного проще, чем хорошо знать С++
Ну а дальше всё просто. Отношение к шаблонам, отношение к STL, отношение к виртуальным функциям, отношение к неявно генерируемому коду (вообще, и в рамках некоторых стратегий, например в рамках RAII), отношение к исключениям, отношение к перегруженным функциям, отношение к операторам, отношение к трюкам и т. д.
Ну а дальше уже прошедшее тут обсуждение о недостатках STL, о Boost, о Loki и т. д.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Pzz, Вы писали:
C>>Я на Ada немного писал, но мне она показалась очень уже многословной. По фичам — больше похоже на какой-нибудь Оберон, но более заточеная на безопасность. Pzz>Говорят, у нее есть поддержка всякой там многопоточности прямо в языке...
Ага, на рандеву. Не сказал бы, что сильно лучше той же Java/C# с synchronized/lock.
Цитирую его слова ( http://www.schlaupelz.de/SZ42/SZ42_software.html ):
> After years of C programming and trying other languages (like C++, > Java, Haskell, Python), I had started to learn Ada early in 2007. This > powerful and beautiful language has become my favourite, and I decided > to do the code development as a programming exercise in Ada.
Кто попало не выигрывает такие конкурсы, правда? Если вообще участвуют.
Может, стоит уделить внимание его словам?
Cyberax пишет:
> Ты знаешь, я как-то привык доверять *моим* ощущениям в тех областях, где > я компетентен.
А, ну да. Если Ада похожа на Оберон, то Ада — это явно не та область,
где компетентен. Логично. Ну тут всё же было мнение человека,
действительно знающего Аду.
Здравствуйте, Kluev, Вы писали:
K>Я вот совсем не знаю Аду, но когда я вижу в коде begin/end моя рука сама тянется к пистолету.
Невроз наверное? Что такого страшного в begin/end?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском