Pull to refresh

Comments 137

UFO just landed and posted this here
Бьерн предвидел похожую реакцию:
Язык C++ разрабатывался для людей, занимающихся программированием всерьез, то есть, для профессионалов своего дела.
C++ по своей сути не предназначен для решения задач средней сложности, с нестрогими требованиями к производительности и надежности программы, равно как он не предназначен для использования не очень опытными программистами со средненькими навыками разработки.

Так что, вы еще не постигли дзен, я считаю! )
UFO just landed and posted this here
91 рождения и 5 лет проф разработки на C++? Даже если вы перестали писать на C++ вчера, это значит что проф-но начали примерно в 17-18 лет — преклоняюсь.
А непроф-но сколько лет до этого писали?
Или проффесионально — это с читается с момента второй программы после «Hello World»?
UFO just landed and posted this here
Профессионалом, обычно, становятся спустя примерно 10 лет практического опыта.
Я, конечно, не специалист по терминам, но, во-первых, он не называл себя профессионалом, он написал, что профессионально работает 5 лет, что значит работает по профессии, а во-вторых, как пишет википедия, многие путают профессионала с мастером.
Вы похоже ссылку перепутали.
Мне кажется, чтобы работать по профессии, необходимо сначала профессией овладеть. Для этого часто идут в ВУЗ, так как одного учебника по языку программирования обычно бывает недостаточно.
В 17 лет туда только еще поступают, как правило.
У вас C++ вызывает настолько сильный батхёрт, что вместо прагматичного чтения новых фичей одного из используемых вами инструментов вы начинаете холиварить?
Статья посвящается интервью со Страуструпом и С++. Не понимаю зачем заводить тут холивар. Не нравится С++ — напишите познавательную статью про Rust. А называть С++, как и любой другой стандартизованный язык, мертворожденным — смешно по моему.
Ну формальное наличие стандартов ни о чём не говорит, есть много вещей вполне себе стандартизованных, но о которых никто ничего не знает. Много вы знаете людей, которые используют, скажем Open Document Architecture ISO 8613 (не путать с OpenDocument ISO/IEC 26300:2006)?

А вот тысячи программистов и тысячи активно развивающихся и поддерживаемых продуктов (включающих в себя всё — от OS до браузеров/редакторов/плееров/CADов и прочего) — это другое дело.

Для меня мертворождённый язык это — скорее Haskell: шума много, толку мало. Много вы вещей можете назвать, которые бы использовали Haskell?

Конечно rust — интересный язык, но он очень молодой и только время покажет есть ли у него хоть какое-то будущее. Если смотреть на «молодые» языки, то хоть как-то состоялся только Go, да и то, в общем, особой популярностью он пока не пользуется (но уж всяко популярнее того же Haskell'я и, пожалуй, популярнее Lisp'а, но сравниться c совершенно не стандартизованными python'ом или PHP ему не дано).
Языков с ISO и ANSI совсем не много. Для нас с индустрией :) важно чтобы написанный однажды в соответствии со стандартом код побежал вне зависимости от компилятора/интерпретатора (ну или с минимальными поправками).
Вы не поверите, но Java с этим справляется гораздо лучше несмотря то, что ISO/ANSI стандарта на неё нету. А вот о переносимости, скажем, Forth'а, Lisp'а, Pascal'я можно даже не мечтать, несмотря на то, что ANSI стандарты на них как раз есть. В большинстве случаев стандарт, собственно, появляется тогда, когда выясняется что у языка уже есть куча диалектов и хочется как-то добиться того, чтобы между ними код можно было переносить. Иногда это помогает, чаще — не помогает. C++ — редкое исключение, когда стандарт воспринимается действительно серьёзно (уж не знаю почему).
Насчет Forth и Pascal ничего не скажу, не читал, не проверял, хотя что там с Паскалем за сложности могут быть не представляю, а вот с Common LISP в этом смысле все очень хорошо. По крайней мере Maxima собирается как минимум с помощью Clozure CL, SBCL и Ecl. А с Java'ой мы еще наплачемся. Oracle нам поможет.
UFO just landed and posted this here
Для счастья нужна генерация примерно такого же машинного кода, только из текста лучше читаемого, быстрее написанного, и без граблей на пути. Для этого и создаются Rust/D.
Познания цикличны:
* сначала мы что то используем неправильно
* потом мы это используем правильно
* потом мы это не используем
* потом специально используем неправильно

Это касается различных языковых конструкций и паттернов. И язык С++ часто демонстрирует такое именно из за его баланса между проектированием (изящество) и производительностью.
Есть два типа языков программирования — те, которые все ругают, и те на которых никто не пишет.
UFO just landed and posted this here
(ну и игрушки всё-таки пока ещё, да)

А так же ещё очень большое количество высокопроизводительного софта с низким потреблением ресурсов, ручным управлением ресурсами, и ещё множество задачек.
p.s: не фанатею от какого либо языка они все со своими заморочками, более того сейчас нет ни одного хорошего и удобного языка, на котором легко писать, и для механизмов работы которого есть реализации в железе. Про вычисления для реального мира вообще молчу, ибо это лютый геморрой везде по причине того, что так работает железо, и именно железо не реализует многих базовых принципов математики.
p.p.s: программирую где от с 2002-2003 г. реальные задачки.
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
Вот это вот ваше «если захотеть». На С++ вон тоже можно вполне писать высокоуровнево и безопасно без заморочек с памятью «если захотеть» (Qt тот же).
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
Даже просто писать код на хаскеле не так уж и проще в виду его функциональной парадигмы, к которой нужно еще привыкнуть. Какой вообще меркой можно сравнить сложность написания высокопроизводительного кода на хаскеле и сложность писать безопасно и высокоуровнево на С++.
Я имел ввиду что хоронят С++ как раз те кто «не захотели», и ведь особо то сложностей нет, используй коллекции да умные указатели, либо готовые фреймворки со своим сборщиком мусора. Что проще, прочитать наконец Страуструпа или учить совершенно другую парадигму а потом еще и заморочки хаскеля которые надо учитывать для высокой производительности?
UFO just landed and posted this here
Ну если насчет меня то я сейчас активно тыкаю Racket для себя (точнее благодаря sicp)
В ответ могу сказать что «Мсье недоучил старое».
UFO just landed and posted this here
Хорошая сборка мусора предполагает что runtime может отличить указатель от данных и имеет возможность перемещать объекты. Для этого язык должен сильно ограничивать программиста в возможности управления памятью.
Вы видимо воспринимайте сборщик мусора как некую мистическую штуку предоставляемую языком, но на самом деле и подсчет ссылок и RAII и пулы объектов это все способы сборки мусора. Грубо говоря С++ предоставляет множество способов сборки мусора в отличии от Java или C#, но программист сам должен выбрать будет ли он заворачивать все в умные указатели, либо лично выделять и удалять память либо придумает какой то свой способ. Вообще С++ дает слишком много свободы, и для программиста очень важно не мотаться от одного способа к другому а выбрать какую-то одну идеологию либо принять ту которой следует фреймворк в котором он работает и стараться следовать ей, да это требует дисциплины, но мне кажется это не такая высокая цена за высочайшую скорость и гибкость.
Предоставлять возможность должен не только язык, но и библиотеки. Если используемая библиотека (в том числе и стандартная) не поддерживает перемещения объектов, то преимущества пакующего сборщика мусора получить не удастся. А в системах с многоуровневой памятью (от кеша до виртуальной памяти) выигрыш в скорости может быть заметным. Да и скорость аллокации выше.
Не понял вашего комментария.
В С++ сборка мусора поддерживается исключительно библиотеками а не языком, причем каждая библиотека использует свою подходящую ей методику управления временем жизни объекта. И при чем здесь вообще аллокация если сборка мусора отвечает только за удаление не используемых объектов а не их создание? Какой еще пакующий сборщик мусора? Сформулирую немного по другому в С++ сборка мусора это не отдельная сущность со своими эвристиками, решающая кому жить а кому умереть, в С++ это просто способ реализовать автоматическое удаление объектов, причем обычно эту задачу перекладывают на сами объекты. Например тот же подсчет ссылок на котором реализовано большинство shared-указателей, сам объект хранит число указателей указывающих на него, при удалении одного указателя этот счетчик уменьшается на единицу, при создании увеличивается на единицу. Как только счетчик обнулится объект уничтожает сам себя. Очень простая идея с минимальными накладными расходами а решает львиную долю проблем слежения за разделяемыми ресурсами. Примерно так выглядит сборка мусора в С++.

P.S. К слову с новым стандартом семантику перемещения (&&) поддерживают все объекты.
Вы считаете что аллокация (реализация new) не обязана знать, как реализуется освобождение?
Сборщик мусора может не только удалить объект, но и переместить его в более подходящее место. При этом он должен скорректировать все ссылки на этот объект.
Накладные расходы счетчика ссылок не надо недооценивать. Инкремент-декримент надо делать при каждом присваивании, в том числе при передачи ссылки в качестве параметра. Кроме того, при изменении счетчика велика вероятность промаха в кеше или странице виртуальной памяти.
Вы считаете что аллокация (реализация new) не обязана знать, как реализуется освобождение?

Зачем ему это знать?
Сборщик мусора может не только удалить объект, но и переместить его в более подходящее место. При этом он должен скорректировать все ссылки на этот объект.

Это ваш сборщик мусора перемещает объекты, в С++ под сборщиком мусора подразумевается всего лишь автоматическое удаление, объект переместится если только ты сам ему скажешь это сделать.
Накладные расходы счетчика ссылок не надо недооценивать. Инкремент-декримент надо делать при каждом присваивании, в том числе при передачи ссылки в качестве параметра. Кроме того, при изменении счетчика велика вероятность промаха в кеше или странице виртуальной памяти.

Про накладные расходы инкремента/декремента вообще смешно, компилятор успешно превращает их в ничто по сравнению со всякими маркировками да перемещениями применимыми в сборщиках встроенных в языки, то же самое и про промахи.
А зачем переопределяют new и delete?
Не известен алгоритм распределения памяти, который бы удовлетворил всех. А разные алгоритмы используют разные структуры данных и delete из одного алгоритма будет некорректно работать с объектом, полученным new другого алгоритма.

Раз уж C++ не позволяет использовать пакующий сборщик мусора, как большинство языков с GC, так не надо утверждать, что он на столько гибкий, что может все на свете и больше ни чего ни кому не надо.
delete из одного алгоритма будет некорректно работать с объектом, полученным new другого алгоритма.

Это вообще пушка, new и delete определяются для класса и если уж их переопределяют так обычно оба, если у вас есть объект то он будет использовать эти new и delete, хоть в какой функции.

Если вам так хочется использовать пакующий сборщик мусора, ради бога, вы можете спуститься вплоть до malloc'ов и alloc'ов и реализовать хоть какое угодно чудное управление памятью, можете даже переписать алокаторы для классов стандартной библиотеки, другое дело что это практически никому не нужно. В С++ используются умные указатели и RAII как самые быстрые. Гибкость С++ в этом плане именно в том что вы можете спускаться хоть до ассемблерных вставок и выбирать то что вам нужно и реализовывать это как хотите, но за это заплатите сложностью. Идеального сборщика мусора тоже не существует и при этом у вас нет альтернативы.
make_shared, к примеру, размещает и объект и счётчик в одном блоке памяти, поэтому промахи кэша вряд ли будут.
Это про другое перемещение.

С выделением памяти есть еще проблема, называющаяся фрагментацией. После удаления объектов остаются дырки, не, которые не удается занять под другие объекты. Эти дырки отъедают реальную физическую оперативную память.
Один из способов борьбы с ней — это перемещать в памяти объекты, чтобы уменьшиеть количество дырок. Вот только при таком перемещении объект меняет адрес и все указатели на него становятся невалидными. Сборщик мусора должен знать, где находятся все указатели и поменять их тоже. Естественно такие хитрые указатели создают приличный overhead, особенно в многопоточной среде. Поэтму в C++ такое не практикуется.
О, спасибо, теперь понял.
Вы не поняли главного: почему это всё ни черта не работает на практике. А не работает это потому, что для всех этих трюков нужна память! Информацию о блоках нужно где-то хранить, информацию о ссылках нужно где-то хранить, многоуровневые конструкции с «дальними» и «ближними» кучами требуют память и т.д. и т.п. Результат? Плачевен: In particular, when garbage collection has five times as much memory as required, its runtime performance matches or slightly exceeds that of explicit memory management. However, garbage collection’s performance degrades substantially when it must use smaller heaps. With three times as much memory, it runs 17% slower on average, and with twice as much memory, it runs 70% slower. Garbage collection also is more susceptible to paging when physical memory is scarce. In such conditions, all of the garbage collectors we examine here suffer order-of-magnitude performance penalties relative to explicit memory management.

Вот и всё. Приехали. Типичная потеря памяти в C++ программах на вышеуказанной фрагментации — 20-30% (иногда больше, тут уж приходится иногда чуток перепроектировать структуры данных и алгоритмы, но это редко случается), то есть «для надёжности» вам реально нужно примерно раза в полтора больше памяти чем при «идеальном» распределении памяти, когда память выделяется ровно тогда, когда нужно, ровно столько, сколько нужно и нет вообще никаких накладных расходов. Но в случае с «прогрессивными» GC вам нужно памяти втрое-впятеро больше! И толку от всех этих возможностей позволяющих «двигать» и «паковать» объекты если в результате вам всё равно нужно ресурсов дофига и больше?
Скорость написания высокопроизводительного ФП-кода в среднем повыше, чем высокопроизводительного кода на C++. Скорость написания обычного кода — радикально выше. Объем ФП-кода всегда радикально меньше.
Но почему-то на практике компании, использующие ФП никак не могут «захватить мир». Парадокс, однако.
Нелепый аргумент из серии «если ты такой умный, чего ж ты такой бедный?» — между успехом компании и используемыми инструментами корелляция есть, но это далеко не единственный фактор.
Не менее нелепая отмазка людей, которым нечего возразить. Если один, конкретный человек не преуспел в жизни при наличии незаурядного ума — то тому могут быть кучи причин. Болезнь, лень, или просто нежелание тратить свою жизнь на зарабатывание денег (да, такое тоже случается), но если у вас есть много людей, то в среднем миллионеры таки будут умнее, чем грузчики и дворники — и это смешно отрицать.

Так бишь о чём мы. Если бы функциональные языки были так хороши, как про них рассказывают, то была бы куча компаний, которые бы на них поднялись — и да, было бы какое-то количество неудач тоже. Но их нету. По крайней мере среди самых крупных и успешных компаний таких не водится. Facebook, использующий, прости господи, PHP (которые обладает кучей недостатков но при этом позволяет проводить кучу странных экспериментов очень быстро) — есть. Google, использующий C++ (то есть язык, на котором код писать сложно и очень дорого, но при этом можно контролировать расход памяти с точностью до байта и иметь очень хорошее представление о том куда уходит время CPU) — тоже есть. Есть также куча компаний оседлавших Java'у (которая позволяет нанять кучу идиотов, написать спецификацию и получить нечто как-то где-то работающее), но куда пропали все апологеты ФП? Что их всех подкашивает на пути к успеху?
В Facebook используется Хаскель для анализа больших массивов данных. Успешные компании, использующие ФП, есть даже в России, посмотрите на Селектел — у них тут на Хабре блог есть.
Я ничего не писал про компании. Только про производительность программиста и объем кода. Компании, использующие ФП, не завоевывают мир, потому что их нет.
Сильная типизация, лёгкие потоки, иммутабельность, чистота, REPL.
Я имел опыт разработки моделей процессоров на SystemC (библиотека для C++) и на Haskell. При сравнимой производительности разработка на Haskell была гораздо удобнее.
Параллельность не использовалась.
Rust стал достаточно стабилен?
До версии 1.0 использовать его слегка страшновато.
UFO just landed and posted this here
Но вы ведь сказали, что " Для системного «программирования всерьёз» есть сишка и Rust.". А теперь Rust в продакшен не надо. У нас с Вами видимо какое-то разное понимание «серьезного» системного программирования.
UFO just landed and posted this here
UFO just landed and posted this here
Про С++11 правильнее говорить не о стабильности а о поддержке его фич компиляторами. В этом плане gcc и clang поддерживают практически все, а вот msvc похуже.
UFO just landed and posted this here
Вообще да, большинство фич с++11 не для общего пользования а для конкретных задач, самые распространенные (лямбды, авто) стабильно работают, даже regex уже запилен, осталась только минимальная поддержка сборщика мусора, а вот с msvc особенно обидно за constexpr но основная часть (по впечатлением от тех кто с ним работал) уже работает.
UFO just landed and posted this here
Rust, Go, Dlang — все претендуют на звание убийцы C++ для разработчиков у которых какая-то непереносимость C++, но хочется производительности, так что есть из чего выбирать. Но говорить что rust занимает сейчас какую-то нишу, а вот C++ нет — очень странно и вообще как-то вне реальности.
Go никак не может быть убийцей C++. Вот Rust и D — да, определенно, однако стабильности им обоим не хватает. И если для Rust еще простительно, релиза еще не было, то у D с этим совсем плохо. Еще в Rust радует, что бэкенд по умолчанию — LLVM.
Go никак не может быть убийцей C++.
Почему нет? Практически всё понятно: Go привлекает скорее любителей python'а и ruby, чем любителей C++, но теоретически — он мог бы быть «убийцей C++».

Еще в Rust радует, что бэкенд по умолчанию — LLVM.
И, собственно, уже поэтому он не может быть «убийцей C++». Также как и Java не может быть «убийцей C++». Ибо одним из центральных свойств языков BCPL, C, теперь C++ — то, что это «ядерные языки». То есть даже не языки, на которых можно написать ядро OS (хотя это тоже показатель), а то, что «с них всё начинается»: компилятор C написан на C, компилятор C++ написан на C++, все (ну хорошо… почти все) библиотеки в системе так или иначе завязаны на библиотеки соотвествующих языков, etc.

Rust на это вроде как не претендует, так какой из него, нафиг, «убийца C++»?
а то, что «с них всё начинается»: компилятор C написан на C, компилятор C++ написан на C++
И как компилировать компилятор Си, написанный на Си? Точно таким же образом можно реализовать и интерпретатор LLVM-кода.
Go привлекает скорее любителей python'а и ruby, чем любителей C++, но теоретически — он мог бы быть «убийцей C++».

А Вы думаете, С++ программисты случайно от него нос воротят? Отсутствие обобщений (generics), а также фокус на богаую стандартную библиотеку делают Go удобным для быстрого прототипирования, где он и соревнуется с python/ruby. Но главное — в обязательном сборщике мусора, который ставит крест на kernel/embedded области. Базовое сравнение есть на Rust wiki.

И, собственно, уже поэтому он не может быть «убийцей C++». Также как и Java не может быть «убийцей C++». Ибо одним из центральных свойств языков BCPL, C, теперь C++ — то, что это «ядерные языки». То есть даже не языки, на которых можно написать ядро OS (хотя это тоже показатель), а то, что «с них всё начинается»: компилятор C написан на C, компилятор C++ написан на C++, все (ну хорошо… почти все) библиотеки в системе так или иначе завязаны на библиотеки соотвествующих языков, etc.

Rust на это вроде как не претендует, так какой из него, нафиг, «убийца C++»?


Rust компилируется в родной машинный код, а сам большей частью написан на Rust. Уже есть несколько проектов операционных систем на нём. Я думаю, уже само их существование сбивает Ваши доводы с ног.
«с них всё начинается»: компилятор C написан на C, компилятор C++ написан на C++

Turbo Pascal написан на Pascal, Javac написан на Java…
Я не понял Ваш аргумент, поясните, пожалуйста. Что значит «с них всё начинается»?
Человек хотел, наверно, сказать, что C и C++ чаще всего используются в качестве нулевого компилятора для языка.
Эмм, может мне кажется, но больше всего непрофессионализм выдает именование «сишка»
UFO just landed and posted this here
Я думал-думал и я все понял. Классика троллинга (толстого), описанная еще на лурке. Приходишь в пост о С++, говоришь что с++ это хрень, ну и т.д. Эх, классика
И какие преимущества у сишки по сравнению с плюсами?

Я понимю, когда сравнивают С++ с чем-то, что в обмен на проивзводительность дает большее удобство разработки, но в чем выигрыш при сравнении с С?
Знаете как это все выглядит?

— Совковая лопата говно, я весь участок штыковой перекопал, очень удобно! 5 лет до этого копал совковой, ну и извращенцы же ее придумали!

Заканчивайте с этим, короче. Эмоции в инженерии — лишнее дело.
Раз ругают — значит пользуются.
Или пользовались когда-то раньше, или наслышаны. Мне вот беглого знакомтсва с PHP уже хватило, чтобы его ругать, и я даже не считаю это предвзятостью.
У C++ есть свои плюсы и минусы а так же свои сферы применения. И конечно есть куча языков которые кому-то нравятся больше и кажутся сделанными лучше. Но на данный момент это один из мейнстрим языков. И применяется он в огромном количестве проектов, а не только в «игрушках и legacy» — это можно понять как по описанию вакансий, так и по популярным open-source репозиториям.
Мне, как пользователю этого языка, интересно узнать что нового войдёт в новый стандарт. И, в данном контексте, мне не интересны альтернативы в виде rust, haskell, lisp, brainfuck, etc.
Держите нас в курсе относительно того что вас интересует
Обойти стороной Rust (как и D) в этой дискуссии было бы ошибкой. Однако, Ваш пост может скорее оттолкнуть потенциальных растовцев (растовщиков? растовчан?). Rust заслуживает лучшего. Дорогие С++-ники, прошу вас оценить этот язык непредвзято. На сегодняшний день это, пожалуй, единственный инструмент для написания C++-совместимого системного кода при безопасной модели памяти.
К сожалению это не так, ни Rust, ни D не подходят, ибо они не в релизе! Пожалуйста не вводите людей в заблуждение.

Открываем вику про Rust, и видим там следующее:
Нижеследующие примеры являются рабочими при сборке с помощью компилятора Rust от 6 мая 2013. В то же время, с учётом того, что язык находится в стадии активной разработки, код может не работать в более поздних версиях.
Hello world:
extern mod std;
fn main() {
let args = os::args();
io::println(fmt!(«hello world from '%s'!», args[0]));
}
Пара примеров реализации функции поиска факториала, в рекурсивном и итеративном стилях:
/* The branches in this function exhibit Rust's optional implicit return values,
which can be utilized where a more «functional» style is preferred.
Unlike C++ and related languages, Rust's `if` construct is an expression
rather than a statement, and thus has a return value of its own. */
fn fac_recur(n: int) -> int {
if n <= 1 { 1 }
else { n * fac_recur(n-1) }
}

fn fac_iter(n: int) -> int {
// Variables must be declared with the `mut` keyword in order to be mutable.
let mut i = 1,
result = 1;
while i <= n {
result *= i;
i += 1;
}
return result; // An explicit return, in contrast to the above.
}


Если такие элементарные вещи могут оказаться не рабочими, то что уж говорить о серьёзной разработке. Мы бы рады перейти, да вот только нет реальных альтернатив, они все в активной разработке :(
Вы слегка передёргиваете. Приведённый код «может оказаться нерабочим» не в том смысле, что будет вести себя некорректно или падать, а в том, что синтаксис или имена методов стандартной библиотеки могли немного измениться с мая 2013 года.

Да и вообще, русская Вики — это Вам не официальная документация. На сайте проекта есть tutorial, manual, API — всё, что душе угодно, притом одновременно и для последнего релиза, и для текущей версии в разработке.

Как только Вы освоили синтаксис и модель памяти Rust — можно начинать писать что-то серьёзное. Авторы языка неформально обещают выпустить версию 1.0 в этом году, так что «готовить сани к лету» можно уже сейчас.
а в том, что синтаксис или имена методов стандартной библиотеки могли немного измениться

Именно так, и нет никакого передёргивания, для продакшена и больших проектов это не применимо. Или Вы предлагаете нанимать человека (людей) который будет правитьпереписывать код раз в пару месяцев? :) Помимо этого всем разработчикам придётся с таким же интервалом переучиваться, нет уж спасибо, рекомендовать экспериментальный и быстро развивающийся язык можно для исследований в области применения этого языка, развития этого языка, и прочих экспериментов, но никак не для реального применения в боевом режиме. К тому же бессмысленно утверждать, что внутри всё реализовано как надо, и не содержит ошибок. Помимо этого нет абсолютно никаких длительных тестов под высокими нагрузками, и их не будет до тех пор пока не появится стабильная (релизная) спецификация.
Авторы языка неформально обещают выпустить версию 1.0 в этом году, так что «готовить сани к лету» можно уже сейчас.

Вот когда выпустят хотя бы 1.0, т.е. первый официальный, а не экспериментальный релиз, вот тогда и попробуем. Да и сами посудите, ведь за полгода — год команда разработчиков может написать довольно большой проект, и тут я опять поднимаю очевидные вопросы — кто будет переписывать этот проект после релиза языка, кто будет заново проводить тестирование всего продукта, а это требуется поскольку реализация начинки изменится. Хоть я и фрилансер, но смена (обновление) компилятора это всегда довольно длительное тестирование, так уж повелось — я не склонен массово одаривать пользователей потенциальными проблемами на ровном месте.

p.s: официальный сайт тоже штудировал, и раз уж речь зашла о модели памяти языка, то вот пища для размышлений:
Memory safety no null or dangling pointers, no buffer overflows

Эта модель прекрасна и удобна. вот только проблема в том, что железо, на котором работает машинный код, полученный из кода языка высокого уровня не поддерживает такую модель памяти, а это значит, что будут обязательные проверки на переполнение буфера в рантайме, избыточные инициализации и проверки указателей, и т.д, а посему рекомендовать такой язык для системного программирования просто не применим. Посмотрите, что используют для системного программирования — там чаще всего голый С, а то и вообще С--, а местами вообще asm, и это не просто так. Высокопроизводительный код обычно на С++ (с низкоуровневыми вставками) поскольку он не сильно оторван от железа, но уже содержит многие полезные механизмы, к примеру безопасную генерацию кода, умные указатели, позволяющие получить полностью контролируемую, и при этом безопасную модель работы с памятью, и т.д.
Именно так, и нет никакого передёргивания, для продакшена и больших проектов это не применимо.

Так и есть. Цель моего коммента — обратить внимание С++ программистов на Rust. Ведь С++14 и C++17 как бы тоже ещё не вышли, так может лучше посмотреть на Rust, чем ждать их?

К тому же бессмысленно утверждать, что внутри всё реализовано как надо, и не содержит ошибок.

Давайте не будем скатываться в банальности, никто такого не утверждал.

Эта модель прекрасна и удобна. вот только проблема в том, что железо, на котором работает машинный код, полученный из кода языка высокого уровня не поддерживает такую модель памяти, а это значит, что будут обязательные проверки на переполнение буфера в рантайме, избыточные инициализации и проверки указателей, и т.д, а посему рекомендовать такой язык для системного программирования просто не применим.

Вы делаете логически необоснованное умозаключение. Если язык близок к железу — то скорость выполнения будет хороша, это понятно. Но Вы утверждаете обратное (если не близок, то скорость пострадает), что ещё надо доказать:

обязательные проверки на переполнение буфера в рантайме: огромная часть доступа к индексам массива в С идёт на перечисление. Используя итераторы в Rust, Вы получите один в один с Си машинный код перечисления элементов массива, без лишних проверок. Что же до остальных — есть функция доступа без проверки на выход за границы, если в каком-то конкретном месте это бьёт по производительности. К тому же LLVM, используемся в Rust компиляторе, вполне неплохо исключает лишние проверки.
избыточные инициализации: во-первых компилятор (и, опять-же, LLVM) достаточно умён, чтобы оптимизировать такие вещи. А во-вторых, Вы видели хоть один проект, где инициализация созданных объектов была проблемой производительности? Я — нет.
проверки указателей: вся прелесть в том, «плохие» указатели устраняются на этапе компиляции, а не в run-time. Тут работает философия «если оно скомпилировалось, то оно работает», заимствованная из Haskell.

Посмотрите, что используют для системного программирования — там чаще всего голый С, а то и вообще С--, а местами вообще asm, и это не просто так.

Что-то я не припомню ни одного серьёзного приложения на С--… Вы ничего не перепутали?
А вообще понятно, что они используют, эти системщики. Rust пытается потеснить эту нишу, как, впрочем, и многие другие.

к примеру безопасную генерацию кода, умные указатели, позволяющие получить полностью контролируемую, и при этом безопасную модель работы с памятью, и т.д.

Да, на С++ можно писать надёжный код. Да и на asm можно. Вся суть-то в том, что на Rust это делать и приятнее, и быстрее.
Я бы сказал, что программисту на любом языке полезно изучать другие технологии, в том числе те, которые применяются в других областях индустрии. Это выводит уровень решения задач на принципиально новый.
кстати автор католик, ездил читать нам лекцию в вателовский университет на паскалевские чтения по тематике Большие числа и Бог
Если кому интересно более детально узнать как развивался C++ советую почитать
вот это.
В статье, в литературе есть же)
А посвежее не существует издания? С учетом С++11?
Насколько я знаю, нету. Книга была опубликована в 1994, а все дальнейшие изменения в языке после 1994 года были сделаны комитетом по стандартизации.
А про С++ Страуструп неплохо рассказывает тут.
Эта книга посвящена скорее истории развития C++, соображениям, которыми руководствовался Страуструп при реализации тех или иных характерных черт этого языка в целом. А о нынешнем C++11 можно ещё посмотреть в той же The C++ Programming Language (4th Edition), на которую Страуструп ссылается в интервью.
Эта книга посвящена скорее истории развития C++, соображениям, которыми руководствовался Страуструп при реализации тех или иных характерных черт этого языка в целом

Вот это и интересно, но в применении к новым фичам, почему они были сделаны так а не иначе.
А про историю и соображения ещё есть неплохая книжка Пионеры программирования, там хоть и не очень подробно, но зато не только С++, но и еще куча разных языков.
Чего бы он там не говорил о кривых учебниках, учить С++ по книгам самого Страуструпа я бы никому не советовал :)
Сразу начинать с него — да, не стоит, а вот после какой-то базы по типу того же Шилдта, можно и Страуструпа взять.
UFO just landed and posted this here
Р. Лафоре «Объектно-ориентированное программирование в С++» — тоже неплохая книга для старта.
Начинал со Страуструпа, все нравилось.
Бьярне рекомендует свою конкретную книгу: Programming: Principles and Practice Using C++. Она расчитана на студентов, которые начинают практически с нуля. Она сам по ней учит. Книгу очень легко читать. Многие другие учебники действительно кривые. Шилдт, между прочим, хороший пример кривого учебника.
UFO just landed and posted this here
Почему-то именно об этой книге Страуструпа у меня сложилось негативное впечатление. Во-первых, как мне кажется она представляет собой дополнительный материал к лекциям автора, т.е. для полного понимания и компиляции некоторых примеров (в том числе и загружаемых исходников) нужны дополнительные разъяснения. Во-вторых имеет слишком уж большой объём. Быть может, она и охватывает студенческий курс, скажем на три семестра, но новичка может отпугнуть и запутать из-за разных тем (там и лексический анализ, и работа с графикой, и обобщённое программирование). Книги по C++ для начинающих не стоит делать больше 300 страниц. Разумеется, такие книги необходимо снабжать аннотированным списком литературы по темам. Минусом является и тот факт, что, значительная часть книги посвящена рисованию и GUI с использованием библиотеки FLTK (на мой взгляд, не самая удобная и популярная библиотека).
Мне его «Design and evolution» очень помогла. И в плане программирования на C++, и в мотивации перехода на другие языки :-).
А мне нравится С++ и чем дальше на нем пишу, тем больше нравится. Сфера его применения достаточно специфична: «надо вложить много времени, но получить очень производительную и гибкую систему» и вместе с тем «пару неверных движений и простреленная нога обеспечена». На С++ невозможно писать идеальный код сразу. Его будешь переписывать и переписывать и каждый раз он будет получаться лучше. Т.е. возможностей и фишечек столько, что в момент написания сознательно половиной из них не пользуешься, чтобы не усложнять то что рано еще усложнять. А потом когда очертания системы уже видны — можно и подкрутить где надо или переписать что смотрится плохо.
Хороший пример применения языка можно посмотреть в CGAL или кошмар из страшного сна, это зависит от подготовки. :) Если в 3 слова: быстро, гибко и сложно.
Кто что скажет про качество переводов приведенных книг?
Профессионально программирую на С++ 15 лет, не профессионально — считай 20 лет. Язык мне нравится, всё устраивает. Но здесь я хотел бы сказать о другом.
При спорах о языке часто забывают, что на самом деле исполняется не тот текст, который написали на определённом языке, а машинный код. И чтобы этот машинный код получить нужен компилятор. И на самом деле быстроту и производительность даёт (или не даёт) по бОльшей части именно этот преобразователь из вашего любимого языка в машинный. А язык программирования — всего-лишь некий удобный инструмент, на котором вам лично удобно разрабатывать определённые решения для опредеённых задач. Для каких-то задач удобнее С++, для каких-то Haskell. Важно лишь понимать, что нужна некая программа, которая сконвертирует ваш любимый Haskell в машинный код.
Но вот что (IMHO) по настоящему интересно — это иметь программы, которые конвертируют один язык в другой. Знаешь ты например только С++, а тебе надо сделать что-то на C#: используешь преобразователь «С++ — C#». Просто в глобальном масштабе следует «заточить» какие-то языки программирования по определённые задачи, а потом написать преобразователи из других языков. Это как в математике: где-то действует математика вещественных чисел, а где-то — комплексных, есть переходы между числами, определены какие-то области использования. На мо взгляд пора перейти к этому и в языках программирования. То есть стОит переходить от неких общих языков программирования к задаче-ориентированным и написанию «переходников» от одних языков к другим.

Всё вышесказанное — только для «мониторинга» общественного мнения по этому вопросу. Насчет «holly-wars» скажу, что каждый язык хорош по своему :)
Профессионально программирую на С++ 15 лет, не профессионально — считай 20 лет. Язык мне нравится, всё устраивает.

Но вот что (IMHO) по настоящему интересно — это иметь программы, которые конвертируют один язык в другой. Знаешь ты например только С++, а тебе надо сделать что-то на C#: используешь преобразователь «С++ — C#».

Вы таки простите но первое со вторым вообще никак не вяжется. Я еще помню конец школы, первый курс, и даже начатые попытки написания транслятора с «паскаля на си» и обратно. И кое какие примитивы он даже переваривал. Но чтобы человек с 10 — 20 летним опытом всерьез предлагал такое, это уже перебор.
Даже если языки схожи по концепциям/парадигмам, после преобразования будет такая каша, что толку от таких исходников уж точно «человеку» не будет. Ну а компилатор выходного языка всегда будет генерить в самом невороятном лучшем случае такой же по скорости/памяти бинарник, а среднем же он будет всегда уступать оригинальному бинарнику.
Чем вас динамические библиотеки не устроили, пишутся на разных языках, подключаются к разным языкам, все что нужно это знать интерфейс входных/выходных данных.
Насчет «но чтобы человек с 10 — 20 летним опытом всерьез предлагал такое, это уже перебор»: мне вот сейчас бывает нужно перевести реализации сложных программ с С++ на JavaScript. И такое возможно, существуют программы-трансляторы. Уверяю Вас, что это полезные программы и многим могут пригодиться. Конечно часть приходится переводить вручную, но хотелось бы иметь некий универсальный инструмент. И очень бы хотелось (уверен это возможно) получать полностью работоспособный код после трансляции любой программы. Это, конечно, сложно и сравнимо по уровню сложности с написанием собственно компилятора языка, но на мой взгляд очень полезно.
В сложных C++ прогах есть куча зависимостей в виде того-же буста, qt-а, сишных библиотек, своих велосипедов с кодогенераторами, etc. Вы знаете штуки, умеющие такое переводить на js? Да ещё и с конвертированием под js-style?
Поддержать несколько разных компиляторов даже для самих плюсов (а так же несколько разных платформ) — уже проблема.
Проблемы я и сам вижу :) Решений вот пока нет, а хотелось бы.
Так, обычно, компилируется в тот же js не сам c++, а промежуточный код, в который преобразует C++, к примеру, clang. А сам промежуточный код, в данном случает LLVM, уже можно скомпилировать в js, или в машинный код.
image
Использование js в качестве бэкэнда clang-а != полноценный транслятор из одного языка в другой.
Да-да, этим и пользуюсь.
Но все-таки пока считаю написание транслятора из С++ скажем в JavaScript напрямую достижимой задачей. Конечно очень сложной, но достижимой. Насчет «кому это нужно» — собственно ради того, чтобы узнать общественное мнение я и написал свой комментарий.
И на самом деле быстроту и производительность даёт (или не даёт) по бОльшей части именно этот преобразователь из вашего любимого языка в машинный.
Компиллятор тоже в некоторой степени ограничен
* Если у вас динамически типизируемый язык, то вам потребуется больший оверхед на поддержку этого счастья. Тут никуда не деться.
* Если у вас есть счетчик ссылок и сборка мусора, то вам потребуется рантайм, чтобы все это дело обсуживать. С другой стороны, у вас больше возможностей по оптимизации структуры памяти и, возможно, меньшее число копирований памяти.
* Если у вас компиллируемый в некоторые модули язык, то вы не сможете провести межмодульную оптимизацию (нельзя заинлайнить вызов функции из другой динамической библиотеки, ничего не поделать)
* Если у вас компиллируемый в машинный код язык, то вы всегда будете компиллировать под некоторую обобщеннцю платформу и не сможете применить некоторые платформозависимые оптимизации.
* Если у вас компиллируемый в машинный код язык, вы не сможете код в рантайме его оптимизировать в соответствии со статистикой использования
Какая грустная у него фамилия. :(

— общество защиты страусов
Прямо говря, не ожидал подобного комметария на Хабре.
Страуструп у меня всегда вызывал анальную панику, ++ итак всегда сложными были. Вместо того, чтобы упростить базовую семантику плюсов хотябы примерно до уровня C# ввели новый еще более усложняющий стандарт безапелиционно, просто перед фактом геморроя поставили, чтобы поддерживать фичи CLR, которые из Шарпа оптимизатором сами делаются.
Потом еще раз, чтобы поддержать C#. Сейчас мать его уже в третий раз.

Я не хочу клеветать на Страуструпа, но по моему он в какой-то истерике.
Вот меня задолбала тема этого обиженного ботана, который не понял вовремя, что ++ меняться пора, а не выцеживать возможности, потому-что у меня ну вообще никаких желаний под плюса разрабатывать даже 11-го стандарта, теперь еще и 14-й — да е#ись он конём, достало! Страуструп
CLR из коробки эту фигню без заморочек дает для C#, у меня кризис, нужны ли мне плюсы? Куда? В мобильные платформы не надо не поддерживается, в промышленности CLR или RTOS работает, кластеры пока даже 11-й ++ не держат самого софта нет. Куда Страус это всё напихать хочет, в какой сегмент??
Мобильные платформы: Android — jne; iOS — ObjectiveC++; WinRt — C++. RTOS (real-time operating system) если писать на языках со сборщиком мусора, автоматически перестают быть «real-time». Кластеры поголовно работают на Linux, где c++ основной язык разработки. А какие оптимизации делаются CLR? Оптимизированные алгоритмы на с++ работают от 2 до 10 раз быстрее, чем аналогичные на C#, как раз за счёт оптимизации компилятором.
Не знаю ни одного случая кроме геймдева, где нужен Objc++. И то изредка в виде отдельно плюсовой библиотеки. Objc и чистый си решает все нужные заказчикам задачи.

Код на Objc++ создает впечатление о человеке, который слабо знает SDK.
Это я для примера написал, так да, лучше писать на том, подо что заточена платформа.
>>> Не знаю ни одного случая кроме геймдева, где нужен Objc++

Да не вопрос — я писал парсер файлов юзая STL. Колеги покрутили пальцем у выска, но впродакшен ушло :)
Я мысленно с вашими коллегами, не обижайтесь :)
Вы знаете про NSScanner и NSRegularExpression?

Вот кстати, как раз сейчас разбираю коредата-обвязку на обжективплюсах. Два года в продакшене валялось. Думаю как недорого выпилить.
В некоторых ситуациях ObjC не дает той скорости, которую дают плюсы.
Работа со строками/коллекциями — не самая сильная сторона Objective-C.
Именно в некоторых случаях и только в некоторых, редких, случаях, когда к задаче необходим объектно ориентированный подход, и в тоже время нужна скорость — да, не спорю, чистые плюсы, без objc прекрасны. Это гейм дев чаще всего: там нужна неслабая объектная модель и скорость.

Всё остальное для лучшей скорости — чистый си.

Реально, я не против плюсов, просто не видел случаев, где он нужен, и где нельзя обойтись другими средствами вместо. Если что, приведите пример задачи.
Реально, я не против плюсов, просто не видел случаев, где он нужен, и где нельзя обойтись другими средствами вместо. Если что, приведите пример задачи.

Отсортировать массив? В статье про это есть. Речь идет о сортировке массива произвольных элементов.
пожалуйста:

enum {
NSOrderedAscending = -1,
NSOrderedSame,
NSOrderedDescending
};

typedef NSInteger NSComparisonResult;

typedef NSComparisonResult (^NSComparator)(id obj1, id obj2);

NSArray — (NSArray *)sortedArrayUsingComparator:(NSComparator)cmptr

NSMutableArray — (void)sortUsingComparator:(NSComparator)cmptr

Ой, ой — а если в массиве не обьекты? И массив не обьект? Вы кажется начинаете забывать что жизнь есть и за пределами Objective-C рантайма.
Хе-хе на Objective-C вообще нельзя написать что-то по настоящему нагруженное (мое мнение), все эти ништяки из фундейшена сводят перфоманс на нет если нужно много операций.
а что именно последнее нагруженное вы имплементили для iOS?

Недавно мы тут с камеры в реальном времени 3d объекты отлавливали. В этом конкретном редком примере плюсы нужны, согласен. Но они чистые, без objc.
Дело было так — приложение клиент-серверной архитектуры, где сервак делали китайци по заказу шведов, обновления для локальной базы на девайсе клиента обеспечивала выкачка некоего файла с текстом до 8 мб с полученого в респонзе на реквест юрл. Файл засорен разнобойной служебной информацией которая нам по сути не нужна, не имеет ничего общего с json/XML. В общем предстояло изобрести мега велик — так вот попытка использовать парсить строки стредствами foundation не выдерживала никакой критики по перформансу, все эти чарактерсеты, и прочие проверки на наличие префикса и суффикса были ужастны, кроме того в словарь часто попадали принятые за корректные данные обрывки служебной информации с крякозябрами (NSString он в любой кодировке NSString), а вот чтение файла простейшими средствами С++ возомело эффект на выходе мы имели стройные UTF8 строки, из которых было очень просто выбросить мелкие изьяны, правда я проиграл на скорости чтения файла (+30%), но скорость парсинга удалось сократить в 4(!) раза.
Работаю в Google. C++11 в полный рост. Кроме мест где надо очень высокая переносимость (C++98) — клиенты.
пользуйтесь C++/CLI — какие проблемы?
Читал и ностальгировал, труд (язык, книги...) Берна дал мне работу(6 лет на плюсах) и крышу над головой. Я слышал как ругали плюсы мои коллеги, но я не когда не видел в них плохого. Плюсы прекрасно справлялись со своей задачей. Но к сожалению ушел от них в веб, рынок провинции диктовал свои правила жизни.
Кто бы в Бьярну передал вопрос?
Amusingly, the history of the evolution of C++ over time can be described as a history of trying to plug the leaks in the string abstraction. Why they couldn't just add a native string class to the language itself eludes me at the moment /Joe Spolski/

Интересно, что историю развития C++ можно описать как историю затыкания дырок в абстракции строк. Уж не знаю, отчего бы не добавить к языку элементарный класс строчек /Джо Спольски/
передайте этому поляку что уже давно std::string or std::wstring
Да свои классы строк с бриджем и куртизанками имеет чуть-ли не каждая вторая сборка библиотек для С++, может имеется виду что всех проблем в стандартной поставке так и не решили?
Да это не поляку нужно.
Дикий разгул самописных строчек уважаемых библиотекарей заставляет стонать, а отказаться от них нельзя.
А строчки надо было в С++ изначально закладывать ещё при создании.
Sign up to leave a comment.

Articles