Интервью с Бьерном Страуструпом о языке C++

image
Считанные часы остались до Нового 2014-го года, в котором в числе прочего всем нам был обещан новый стандарт C++14. Однако он будет не большим самостоятельным обновлением, а лишь доработкой C++11, багфиксом, который придаст текущей версии языка завершенный вид. На этом фоне Уильям Вонг (англ. William Wong) от ресурса electronicdesign.com взял интервью у Бьерна Страуструпа (дат. Bjarne Stroustrup), создателя C++. Беседа затронула несколько тем: от истории разработки C++ и особенностей стандарта C++11 до проблемы обучения этому языку программирования.

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



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

Translated from an article produced by Electronic Design, October 29, 2013, electronicdesign.com/dev-tools/interview-bjarne-stroustrup-discusses-c


На сегодняшний день языки программирования C и C++ являются самыми востребованными в области встраиваемых (embedded) систем, а также в задачах построения платформ для сторонних приложений. Автором C++ является Бьерн Страуструп. Он и поныне принимает активное участие в разработке стандартов этого языка программирования, в том числе последнего — C++11. Многое об этом языке он писал в своих книгах, например, в “Programming: Principles and Practice using C++” . Бьерн Страуструп любезно согласился ответить на несколько вопросов о самом языке C++ и о его разработке.

Как вы пришли к разработке C++?

Я работал над проектом, который позволил бы разделить ядро Unix на несколько частей, исполняемых мультипроцессором или высокопроизводительной локальной сетью. И мне потребовался инструмент, который позволил бы работать с аппаратной частью, обеспечивал бы хорошую производительность для задач системного программирования, а также мог бы использоваться для работы над системой со сложной архитектурой. Однако на тот момент (1979-1980 гг.) ни один из существующих языков программирования не удовлетворял всем трем условиям сразу. Поэтому я решил добавить к C концепцию классов — наподобие той, что была в Simula. Вначале я реализовал проверки и преобразования аргументов функций (впоследствии они стали прототипами функций), конструкторы, деструкторы, а также простейшее наследование. Первая версия языка C++ называлась «C with Classes». Кстати, любопытно, что для простейшей поддержки обобщенного программирования (generic programming) в ней использовались макросы. В дальнейшем я понял, что такой подход не обеспечивает должной масштабируемости, и вместо макросов добавил шаблоны.

Я совершенствовал архитектуру и реализацию языка C++ следующие несколько лет, вплоть до его коммерческого релиза в 1985 году. В то время производительность и скорость обращения к аппаратной части были очень важными характеристиками, впрочем, как и сегодня. Я счел необходимым реализовать в C++ все возможности языка C, причем сделать их не менее эффективными. Например, на ранних этапах я обнаружил, что структуры, используемые для реализации конструктора копирования, занимали на 3% больше памяти, чем в C. Я решил, что так быть не должно, и к концу недели все исправил. Чтобы программистам не пришлось отказываться от классов без какой-либо потери процессорного времени, были также добавлены встраиваемые (inline) функции. Я вообще был уверен в том, что используемые средства должны быть не только выразительными, но и достаточно эффективными, чтобы их можно было использовать в приложениях с самыми высокими требованиями.

К чему вы стремились при разработке языка C++?

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

Это требование влечет за собой использование строгой статической типизации, в отличие от слабой типизации в C.

Язык C++ разрабатывался для людей, занимающихся программированием всерьез, то есть, для профессионалов своего дела. Он может использоваться — и используется — новичками, но часто это приводит к разным недоразумениям и жалобам на то, что не каждому дано научиться программировать на C++ и что есть вещи, которые очень сложно реализовать на этом языке. Разумеется, не существует универсального языка программирования для всего и вся, C++ и не создавался таким. Однако этот язык весьма эффективен в тех областях, для которых он был разработан, как то системное программирование или программирование программ с серьезными ограничениями на ресурсы компьютера. C++ нет равных там, где его мощь действительно нужна, и меня не сильно заботит, что вместо этого можно написать простенькое веб-приложение на JavaScript или Ruby. C++ по своей сути не предназначен для решения задач средней сложности, с нестрогими требованиями к производительности и надежности программы, равно как он не предназначен для использования не очень опытными программистами со средненькими навыками разработки. Безусловно, он может использоваться в таких условиях и сегодня это широко практикуется, но существует множество других языков программирования, которые подошли бы для этого намного лучше.

О ключевых принципах, которых я придерживался при разработке C++, я рассказал в своей книге«The Design and Implementation of C++» и в двух статьях, написанных для конференции «History Of Programming Languages». Если вкратце, то я ставил такие цели:

  • эффективная поддержка абстракции данных. Код, использующий абстракции, не должен допускать никаких накладных расходов по сравнению кодом без ее использования,
  • принципы взаимодействия языка C++ и его компилятора с компьютером должны быть максимально похожими на те, что были у C,
  • существенная гибкость кода, которую можно достичь при помощи абстракций, а также
  • надежность кода, которая достигается при помощи строгой статической типизации.


Если в общем, C++ призван помочь в написании качественного программного кода. Профессиональные программисты в реальной жизни сталкиваются со сложными задачами, и этот язык программирования во многом упрощает их жизнь.

Хотя, конечно, не получится достигнуть все эти цели сразу, и C++ не идеален. Однако, несмотря на бесчисленные попытки создать язык вместо него, C++ со своим строгим дизайном остается лучшим решением для самых разных практических задач.

Вы принимали участие в разработке стандарта языка C++ с самого начала. Сильно ли он изменился со временем? Кто занимается разработкой новых стандартов?


Сложно сказать. Разработка формального стандарта — это очень непростое и, как правило, муторное дело. Им занимаются люди с большим опытом, однако все они — специалисты по совершенно разным областям программирования, и каждый имеет свое видение стандарта. Так что прийти к единому мнению может быть сложно и накладно по времени, но это необходимо: удовлетворить всем требованиям сразу не получится, а принуждать программистов пользоваться принципиально новыми инструментами нельзя. Прогресс происходит только когда в стандарт включаются дополнения, важность которых общепризнана. Нельзя принимать участие в комитете и при этом постоянно зацикливаться на мелочах. Нужно уметь видеть всю картину в целом и приходить к общему мнению с остальными. По моим подсчетам, в комитет входит около сотни организаций и, может, больше трехсот собственно разработчиков. Это в два-три раза больше, чем было раньше. Только на последних собраниях присутствовало около ста человек.

В 2014 году мы планируем выпустить новый стандарт, C++14. В нем будут минимальные нововведения, а также несколько исправлений, за их необходимость уже проголосовало большинство комитета. Я рассчитываю, что в 2014 году все уже будут использовать C++14, а после этого мы планируем выпустить C++17 в 2017 году. Но это обновление будет уже намного существенней, так что тут сложно судить о сроках.

Комитет по разработке стандартов ISO C++ сам по себе не располагает какими-либо ресурсами, будь то деньги или штатные разработчики. Он полностью основан на средствах его участников. Например, чтобы входить в состав комитета, они платят 1200 долларов ежегодно. Всякий может заявить, что, мол, в C++ нет нормальной библиотеки для создания графических интерфейсов или нормальной поддержки параллелизма задач. Да, мы в курсе. Чем жаловаться, лучше бы помогли довести эти задачи до ума. У нас очень мало прикладных программистов, и часто получается так, что нововведения создаются в угоду интересов одного конкретного разработчика.

Многие программисты при разработке встроенных систем предпочитают использовать C, потому что он проще, чем C++, и больше подходит для разработки под аппаратное обеспечение. Действительно ли сложность C++ должна быть камнем преткновения для разработки встроенных систем?


Вовсе нет. Если вы придерживаетесь C-стиля программирования, то C++ окажется ничуть не сложнее C, причем он тоже подходит для разработки под аппаратное обеспечение. И уж точно C++ намного эффективнее, чем C. Я никогда не видел такой программы на C++, которую можно было бы так переписать на C, что у нее будет меньший объем кода, она будет производительней, она будет лучше сопровождаться — в общем, будет эффективнее. Не верю, что такое возможно.

Миф о том, что «C лучше C++», сбивает с толку очень многих начинающих программистов. Так, например, когда они сталкиваются с проблемами, они постоянно пытаются что-то выдумывать и применять совершенно нетривиальные вещи, а не использовать простые и мощные инструменты. В конце концов, у них получается очень сложный и запутанный код, который они в силу своих заблуждений принимают за эталон. Вся эта ситуация меня просто поражает. Если человек берется за что-то, а ему постоянно твердят, что это очень сложно и бесполезно, то у него в итоге ничего и не получится. Единственная вразумительная причина, из-за которой, как я знаю, используют чистый C, а не C++, — это ограниченные возможности конкретной платформы.

Однако студентов и вообще новичков в изучении C++ нельзя винить, потому что их ошибки часто зарождаются в процессе освоения университетского курса программирования. Однажды, лет десять назад, мне довелось вести его у первокурсников. Я заглянул в учебники — и просто поразился: вместо понятных и простых в использовании конструкций C++ в книгах в начале рассматривалась куча разных неочевидных мелочей языка C, а инструменты С++ преподносились как нечто очень сложное. Это не отпугивало только тех, кто хотел серьезно заниматься программированием.

Вот серьезно, скажите: неужели вектора из стандартной библиотеки сложнее массивов из C? Или, например, почему студентов приучают к функции qsort(), хотя sort() и эффективнее, и универсальнее? У C++ более строгая типизация, чем у C, за счет этого объектный код обрабатывается быстрее.

Еще в учебниках часто описывают C++ как провалившуюся попытку создания чистого объектно-ориентированного языка программирования. Такое утверждение как правило иллюстрируется целой простыней кода, в которой практически вся архитектура разбита на запутанную иерархию классов, унаследованных друг от друга. В итоге получается совершенно не характерная для C++ связанность. Такой код напоминает скорее программу на Java, и, что самое печальное, работает он обычно медленно.

Мне тоже не нравится C++ таким, каким его представляют авторы тех учебников. В ответ я написал свою книгу для студентов и самоучек — «Programming: Principles and Practice using C++». Для ее изучения опыт программирования не обязателен, однако она вызвала интерес и среди опытных разработчиков. Только если вам нужен просто обзор C++11, то эта книга будет довольно большой. Для этой цели я порекомендовал бы книгу «A Tour of C++». В ней описаны все ключевые моменты ISO C++ и стандартной библиотеки всего на 180 страницах. Стандарт C++11 полностью поддерживается компиляторами Clang и GCC, частично — Microsoft C++ и многими другими, правда, боюсь, на менее популярных платформах он может выполняться некорректно.


В C++ 11 было много нововведений, в том числе лямбда-выражения и поддержка многопоточного программирования. Как вы считаете, оказались ли они востребованными?


Для работы с потоками мне постоянно приходилось пользоваться сторонними библиотеками. Они были хороши, но последние пятнадцать лет я хотел добавить поддержку потоков именно в стандарт, чего мы наконец и достигли. С точки зрения параллельного программирования ключевые новшества C++11 состоят в организации памяти (которую, к слову, заимствовали и для языка C), а также портируемости многопоточных программ. Однако если вы программируете на уровне потоков и барьеров, то самым главным для вас может оказаться безопасное преобразование типов (type safety): для разделения и передачи данных между потоками больше не требуется никаких макросов или void**. Впрочем, для кого-то также важны инструменты и для lock-free программирования.

Что касается лямбда-выражений, то я примерно лет десять работал над такой их реализацией в языке C++, от которой было бы больше пользы, чем вреда. У сторонних библиотек как правило страдает производительность. Нам же удалось добиться для лямбда-выражений производительности, сравнимой с циклом for. Приведу пример:

double sum = 0;
for (int i=0; i<v.size(); ++i) sum += v[i];    // array style


double sum = 0;
for (auto p = v.begin(); p!=v.end(); ++p) sum += *p; // pointer style


double sum = 0;
for_each(v.begin(),v.end(), [&](double d) { sum += d; });   // algorithm style


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

Я бы применял лямбда-выражения всего в нескольких случаях. В таком, например:

sort(v, [](const string& a, const string& b) { return a>b; }); // sort in reverse order


Лямбда-выражения — новый и довольно мощный инструмент. Подвох в том, что такие вещи программисты любят использовать буквально повсюду, пока не понимают, чем это обернется в дальнейшем. Мне, например, кажется, что функцию и функциональные объекты лучше объявлять отдельно. У нужной операции тогда будет свое собственное имя, которое можно легко вызвать из разных участков программы.

Также лямбда-выражения открывают большой простор для практики написания кода. Здесь, наверное, не место учить вас C++11, но позвольте мне привести один пример:

template<typename C, typename V>
vector<Value_type<C>*> find_all(C& cont, V v)  // find all occurrences of v in cont
{
    vector<Value_type<C>*> res;

    for (auto& x : cont)
        if (x==v)
            res.push_back(&x);
    return res;
}


В этом коде я применил несколько новых для C++ вещей. Цикл for, например, здесь читается как «для всех x из cont» и упрощает перебор контейнера cont. Объявление auto& x показывает, что x должна быть ссылкой на тип элементов инициализирующего контейнера, в данном случае — на тип элементов cont. Данный цикл собирает адреса всех вхождений v в cont и складывает их в вектор указателей res. Так что эти конструкции — не больше чем синтаксический сахар, хотя они весьма удобны.


Существенное же нововведение заключено в return: обратите внимание, что я вернул вектор по значению. В C++98 этот оператор возврата создал бы копию res, а ведь на деле он может оказаться большим и состоять из тысяч элементов. С точки зрения производительности это было бы весьма опрометчиво. А в C++11 у векторов есть так называемый конструктор перемещения (move constructor), который вместо копирования «заимствует» представление res (в сущности, всего три указателя) для использования на месте вызова функции find_all(), а сам вектор оставляет пустым. После выполнения return мы больше никогда не сможем использовать res. Таким образом, возврат вектора по значению обойдется максимум в шесть присваиваний, вне зависимости от размера вектора.

Конструкторы перемещения — довольно простой инструмент. Он доступен каждому программисту, и, кроме того, реализован во всех контейнерных классах стандартной библиотеки. Это позволяет без труда возвращать из функций большие объекты и не ломать лишний раз голову над управлением памятью.

Протестировать функцию find_all() можно следующим образом:

void test()
{
    string m {"Mary had a little lamb"};

    for (const auto p : find_all(m,'a'))            // p is a char*
        if (*p!='a')
            cerr << "string bug!\n";

    vector<string> v {"Mary”, “lamb", “Mary”, “mary”, “wolf”};

    for (const auto p : find_all(v,”Mary”))    // p is a string*
        if (*p!=”Mary”)
            cerr << "vector<string> bug!\n";
}


Попробуйте написать тот же код без применения шаблонов и нововведений C++11 и сравните результаты.


На эту тему рекомендую прочесть «A Tour of C++», за деталями же обратитесь к четвертому изданию книги «The C++ Programming Language».

Какие часто встречаемые у современных C++-программистов ошибки вы можете отметить?

Они почему-то часто думают, что должны выбирать между эффективным и изящным кодом. Они либо ограничивают себя низкоуровневыми возможностями языка (ради «эффективности»), либо выстраивают огромную архитектуру «на все случаи жизни» (полагая такой код весьма элегантным). На мой же взгляд, идеал состоит в сочетании максимальной эффективности и наиболее оптимальной архитектуры. Так происходит, когда решение программиста самым оптимальным образом удовлетворяет условиям задачи, но это, разумеется, не всегда возможно. Редко получается добиться этого с первой попытки, но так случается довольно часто, насколько это возможно для идеала.

Прежде чем отказываться от возможностей C++, вроде классов или шаблонов, попробуйте сперва рассмотреть их базовое применение и попрактиковаться. Обоснованный выбор приведет вас намного дальше, чем шаги, предпринятые наугад. Не обязывайте себя сооружать огромные иерархии классов или писать запутанный мета-код с помощью шаблонов: некоторые из самых мощных возможностей C++ очень просты. Лучший путь к написанию эффективного кода — не усложнять его без необходимости.

Чем вы любите заниматься в свободное время?

Мне интересно путешествовать по разным местам. Еще я люблю выходить на пробежки. Также я увлекаюсь фотографией, мне нравится слушать музыку и читать — художественную и историческую литературу. Время стараюсь проводить с родными и близкими. Само собой, программирование мне тоже порой доставляет немало удовольствия, но вопрос, должно быть, не о работе. Мне нравится заниматься исследованиями, собирать сложные программные системы. Как кто-то сказал, «не могу поверить, что мне за это еще и платят!»

Примечания переводчика


  1. «Программирование. Принципы и практика использования C++» в переводе Дмитрия Клюшина, издательство «Вильямс». назад
  2. О типизации см. статью Ликбез по типизации в языках программирования. назад
  3. Вероятно, здесь все-таки имеется в виду книга «The Design and Evolution of C++» — «Дизайн и эволюция C++» в переводе издательства «Питер». назад
  4. Модель памяти C++11 подробно рассмотрена в статье Lock-free структуры данных. Основы: Модель памяти. назад
  5. Краткий обзор move semantics в C++11 приведен в статье Move semantics в C++11 и STL-контейнеры. назад
  6. В целом ключевые нововвдения C++11 (в том числе и вышеупомянутые) освещены в статье Десять возможностей C++11, которые должен использовать каждый C++ разработчик.
  7. В русском переводе Николая Мартынова, издательство «Бином», книга называется «Язык программирования C++», однако я смог отыскать только перевыпуск бородатого, неактуального издания 2001-го года. Других переводов не нашел вовсе. назад
Поделиться публикацией
Комментарии 137
    –37
    Как бы это поделикатнее… Нет, спасибо, в общем. rust-lang.org
      +31
      Бьерн предвидел похожую реакцию:
      Язык C++ разрабатывался для людей, занимающихся программированием всерьез, то есть, для профессионалов своего дела.
      C++ по своей сути не предназначен для решения задач средней сложности, с нестрогими требованиями к производительности и надежности программы, равно как он не предназначен для использования не очень опытными программистами со средненькими навыками разработки.

      Так что, вы еще не постигли дзен, я считаю! )
        –23
        У меня опыт профессиональной разработки на С++ около 5 лет, но последнее время, слава богу, я вовсе перестал его использовать. Работаю с видеокодеками на сишке, уровнем повыше идут обвязки на лиспе, для себя пишу на хаскеле, по-моему, это можно назвать «программированием всерьёз». Уродливей С++ языка не видел. Можете считать это хабрасуицидом, минусовать сколько влезет — всё это не сделает С++ хоть каплю лучше, с по-настоящему строгой типизацией, LALR-грамматикой, человеческим управлением памятью, ООП и метапрограммированием, а так же отсутствием UB и ID на каждом углу и всего прочего в таком духе. Язык мертворождённый изначально.
          +32
          91 рождения и 5 лет проф разработки на C++? Даже если вы перестали писать на C++ вчера, это значит что проф-но начали примерно в 17-18 лет — преклоняюсь.
          А непроф-но сколько лет до этого писали?
          Или проффесионально — это с читается с момента второй программы после «Hello World»?
            –13
            C 17 лет по ТК. Спасибо.
              +7
              Профессионалом, обычно, становятся спустя примерно 10 лет практического опыта.
                +15
                Я, конечно, не специалист по терминам, но, во-первых, он не называл себя профессионалом, он написал, что профессионально работает 5 лет, что значит работает по профессии, а во-вторых, как пишет википедия, многие путают профессионала с мастером.
                  +15
                  Вы похоже ссылку перепутали.
                  +2
                  Мне кажется, чтобы работать по профессии, необходимо сначала профессией овладеть. Для этого часто идут в ВУЗ, так как одного учебника по языку программирования обычно бывает недостаточно.
                  В 17 лет туда только еще поступают, как правило.
            +21
            У вас C++ вызывает настолько сильный батхёрт, что вместо прагматичного чтения новых фичей одного из используемых вами инструментов вы начинаете холиварить?
              +26
              Статья посвящается интервью со Страуструпом и С++. Не понимаю зачем заводить тут холивар. Не нравится С++ — напишите познавательную статью про Rust. А называть С++, как и любой другой стандартизованный язык, мертворожденным — смешно по моему.
                +3
                Ну формальное наличие стандартов ни о чём не говорит, есть много вещей вполне себе стандартизованных, но о которых никто ничего не знает. Много вы знаете людей, которые используют, скажем Open Document Architecture ISO 8613 (не путать с OpenDocument ISO/IEC 26300:2006)?

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

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

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

                Это касается различных языковых конструкций и паттернов. И язык С++ часто демонстрирует такое именно из за его баланса между проектированием (изящество) и производительностью.
                +34
                Есть два типа языков программирования — те, которые все ругают, и те на которых никто не пишет.
                  –22
                  С++ в большинстве случаев ругают как раз те, кто на нём собаку съел. Справедливо и обратное: восторгаются им как правило те, кто кроме него ничего другого не знает, нормальных языков не видел, вот и сравнивать не с чем. Есть и прагматики, разумеется, для которых это лишь инструмент (себя причисляю в эту категорию), но использование любого инструмента оправдано лишь при наличии ниши. У С++ этой ниши давно нет, только легаси (ну и игрушки всё-таки пока ещё, да). Для системного «программирования всерьёз» есть сишка и Rust.
                    +13
                    (ну и игрушки всё-таки пока ещё, да)

                    А так же ещё очень большое количество высокопроизводительного софта с низким потреблением ресурсов, ручным управлением ресурсами, и ещё множество задачек.
                    p.s: не фанатею от какого либо языка они все со своими заморочками, более того сейчас нет ни одного хорошего и удобного языка, на котором легко писать, и для механизмов работы которого есть реализации в железе. Про вычисления для реального мира вообще молчу, ибо это лютый геморрой везде по причине того, что так работает железо, и именно железо не реализует многих базовых принципов математики.
                    p.p.s: программирую где от с 2002-2003 г. реальные задачки.
                      –21
                      Согласитесь, это очень узкая ниша, когда нужно всё вместе и сразу. Если речь не идёт об embedded, то OCaml или Haskell (особенно для интесивной математики) в плане производительности будут ничем не хуже, а порой и лучше, если захотеть. Если идёт, то так же, но с поправками. Но, учитывая, что таких задач не очень много, в 21 веке стоит думать скорее об эффективном распараллеливании, в том числе и на GPU.
                      • НЛО прилетело и опубликовало эту надпись здесь
                          –9
                          Про его ADT, высочайший уровень абстракций, расширения компилятора, скорость разработки, сравнимую с использованием скриптовых языков, при этом с производительностью, близкой к сишке (если захотеть) вы конечно же забыли. В любом случае, господа, я не хочу ни с кем спорить и тем более навязывать своё мнение — это пустое. Давайте лучше займёмся чем-нибудь более продуктивным.
                            +7
                            Вот это вот ваше «если захотеть». На С++ вон тоже можно вполне писать высокоуровнево и безопасно без заморочек с памятью «если захотеть» (Qt тот же).
                              –8
                              Можно. Но разной ценой. И писать на хаскеле высокопроизводительный код, скажу я вам, проще.
                              • НЛО прилетело и опубликовало эту надпись здесь
                                +4
                                Даже просто писать код на хаскеле не так уж и проще в виду его функциональной парадигмы, к которой нужно еще привыкнуть. Какой вообще меркой можно сравнить сложность написания высокопроизводительного кода на хаскеле и сложность писать безопасно и высокоуровнево на С++.
                                Я имел ввиду что хоронят С++ как раз те кто «не захотели», и ведь особо то сложностей нет, используй коллекции да умные указатели, либо готовые фреймворки со своим сборщиком мусора. Что проще, прочитать наконец Страуструпа или учить совершенно другую парадигму а потом еще и заморочки хаскеля которые надо учитывать для высокой производительности?
                                  –9
                                  учить совершенно другую парадигму
                                  Мсье так не любит учиться новому?
                                    +8
                                    Ну если насчет меня то я сейчас активно тыкаю Racket для себя (точнее благодаря sicp)
                                    В ответ могу сказать что «Мсье недоучил старое».
                                      –3
                                      Ну вам виднее, конечно, да :)
                                    0
                                    Хорошая сборка мусора предполагает что runtime может отличить указатель от данных и имеет возможность перемещать объекты. Для этого язык должен сильно ограничивать программиста в возможности управления памятью.
                                      +1
                                      Вы видимо воспринимайте сборщик мусора как некую мистическую штуку предоставляемую языком, но на самом деле и подсчет ссылок и RAII и пулы объектов это все способы сборки мусора. Грубо говоря С++ предоставляет множество способов сборки мусора в отличии от Java или C#, но программист сам должен выбрать будет ли он заворачивать все в умные указатели, либо лично выделять и удалять память либо придумает какой то свой способ. Вообще С++ дает слишком много свободы, и для программиста очень важно не мотаться от одного способа к другому а выбрать какую-то одну идеологию либо принять ту которой следует фреймворк в котором он работает и стараться следовать ей, да это требует дисциплины, но мне кажется это не такая высокая цена за высочайшую скорость и гибкость.
                                        0
                                        Предоставлять возможность должен не только язык, но и библиотеки. Если используемая библиотека (в том числе и стандартная) не поддерживает перемещения объектов, то преимущества пакующего сборщика мусора получить не удастся. А в системах с многоуровневой памятью (от кеша до виртуальной памяти) выигрыш в скорости может быть заметным. Да и скорость аллокации выше.
                                          0
                                          Не понял вашего комментария.
                                          В С++ сборка мусора поддерживается исключительно библиотеками а не языком, причем каждая библиотека использует свою подходящую ей методику управления временем жизни объекта. И при чем здесь вообще аллокация если сборка мусора отвечает только за удаление не используемых объектов а не их создание? Какой еще пакующий сборщик мусора? Сформулирую немного по другому в С++ сборка мусора это не отдельная сущность со своими эвристиками, решающая кому жить а кому умереть, в С++ это просто способ реализовать автоматическое удаление объектов, причем обычно эту задачу перекладывают на сами объекты. Например тот же подсчет ссылок на котором реализовано большинство shared-указателей, сам объект хранит число указателей указывающих на него, при удалении одного указателя этот счетчик уменьшается на единицу, при создании увеличивается на единицу. Как только счетчик обнулится объект уничтожает сам себя. Очень простая идея с минимальными накладными расходами а решает львиную долю проблем слежения за разделяемыми ресурсами. Примерно так выглядит сборка мусора в С++.

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

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

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

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

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

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

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

                                                С выделением памяти есть еще проблема, называющаяся фрагментацией. После удаления объектов остаются дырки, не, которые не удается занять под другие объекты. Эти дырки отъедают реальную физическую оперативную память.
                                                Один из способов борьбы с ней — это перемещать в памяти объекты, чтобы уменьшиеть количество дырок. Вот только при таком перемещении объект меняет адрес и все указатели на него становятся невалидными. Сборщик мусора должен знать, где находятся все указатели и поменять их тоже. Естественно такие хитрые указатели создают приличный overhead, особенно в многопоточной среде. Поэтму в C++ такое не практикуется.
                                                  0
                                                  О, спасибо, теперь понял.
                                                    +4
                                                    Вы не поняли главного: почему это всё ни черта не работает на практике. А не работает это потому, что для всех этих трюков нужна память! Информацию о блоках нужно где-то хранить, информацию о ссылках нужно где-то хранить, многоуровневые конструкции с «дальними» и «ближними» кучами требуют память и т.д. и т.п. Результат? Плачевен: 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 вам нужно памяти втрое-впятеро больше! И толку от всех этих возможностей позволяющих «двигать» и «паковать» объекты если в результате вам всё равно нужно ресурсов дофига и больше?
                                          –1
                                          Скорость написания высокопроизводительного ФП-кода в среднем повыше, чем высокопроизводительного кода на C++. Скорость написания обычного кода — радикально выше. Объем ФП-кода всегда радикально меньше.
                                            +2
                                            Но почему-то на практике компании, использующие ФП никак не могут «захватить мир». Парадокс, однако.
                                              +2
                                              Нелепый аргумент из серии «если ты такой умный, чего ж ты такой бедный?» — между успехом компании и используемыми инструментами корелляция есть, но это далеко не единственный фактор.
                                                0
                                                Не менее нелепая отмазка людей, которым нечего возразить. Если один, конкретный человек не преуспел в жизни при наличии незаурядного ума — то тому могут быть кучи причин. Болезнь, лень, или просто нежелание тратить свою жизнь на зарабатывание денег (да, такое тоже случается), но если у вас есть много людей, то в среднем миллионеры таки будут умнее, чем грузчики и дворники — и это смешно отрицать.

                                                Так бишь о чём мы. Если бы функциональные языки были так хороши, как про них рассказывают, то была бы куча компаний, которые бы на них поднялись — и да, было бы какое-то количество неудач тоже. Но их нету. По крайней мере среди самых крупных и успешных компаний таких не водится. Facebook, использующий, прости господи, PHP (которые обладает кучей недостатков но при этом позволяет проводить кучу странных экспериментов очень быстро) — есть. Google, использующий C++ (то есть язык, на котором код писать сложно и очень дорого, но при этом можно контролировать расход памяти с точностью до байта и иметь очень хорошее представление о том куда уходит время CPU) — тоже есть. Есть также куча компаний оседлавших Java'у (которая позволяет нанять кучу идиотов, написать спецификацию и получить нечто как-то где-то работающее), но куда пропали все апологеты ФП? Что их всех подкашивает на пути к успеху?
                                                  +1
                                                  В Facebook используется Хаскель для анализа больших массивов данных. Успешные компании, использующие ФП, есть даже в России, посмотрите на Селектел — у них тут на Хабре блог есть.
                                                    0
                                                    Тем не менее, Facebook экспериментирует не только с PHP. Совсем недавно они начали использовать D как бекэнд.
                                                  0
                                                  Я ничего не писал про компании. Только про производительность программиста и объем кода. Компании, использующие ФП, не завоевывают мир, потому что их нет.
                                        +2
                                        Сильная типизация, лёгкие потоки, иммутабельность, чистота, REPL.
                                          +1
                                          Я имел опыт разработки моделей процессоров на SystemC (библиотека для C++) и на Haskell. При сравнимой производительности разработка на Haskell была гораздо удобнее.
                                          Параллельность не использовалась.
                                      +8
                                      Rust стал достаточно стабилен?
                                      До версии 1.0 использовать его слегка страшновато.
                                        –7
                                        В продакшен пока не надо.
                                          +15
                                          Но вы ведь сказали, что " Для системного «программирования всерьёз» есть сишка и Rust.". А теперь Rust в продакшен не надо. У нас с Вами видимо какое-то разное понимание «серьезного» системного программирования.
                                            –5
                                            Зато честно. Всерьёз можно и для себя, и для OSS, не забывайте.
                                        • НЛО прилетело и опубликовало эту надпись здесь
                                            +7
                                            Про С++11 правильнее говорить не о стабильности а о поддержке его фич компиляторами. В этом плане gcc и clang поддерживают практически все, а вот msvc похуже.
                                            • НЛО прилетело и опубликовало эту надпись здесь
                                                +3
                                                Вообще да, большинство фич с++11 не для общего пользования а для конкретных задач, самые распространенные (лямбды, авто) стабильно работают, даже regex уже запилен, осталась только минимальная поддержка сборщика мусора, а вот с msvc особенно обидно за constexpr но основная часть (по впечатлением от тех кто с ним работал) уже работает.
                                        • НЛО прилетело и опубликовало эту надпись здесь
                                            +12
                                            Rust, Go, Dlang — все претендуют на звание убийцы C++ для разработчиков у которых какая-то непереносимость C++, но хочется производительности, так что есть из чего выбирать. Но говорить что rust занимает сейчас какую-то нишу, а вот C++ нет — очень странно и вообще как-то вне реальности.
                                              +2
                                              Go никак не может быть убийцей C++. Вот Rust и D — да, определенно, однако стабильности им обоим не хватает. И если для Rust еще простительно, релиза еще не было, то у D с этим совсем плохо. Еще в Rust радует, что бэкенд по умолчанию — LLVM.
                                                –2
                                                Go никак не может быть убийцей C++.
                                                Почему нет? Практически всё понятно: Go привлекает скорее любителей python'а и ruby, чем любителей C++, но теоретически — он мог бы быть «убийцей C++».

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

                                                Rust на это вроде как не претендует, так какой из него, нафиг, «убийца C++»?
                                                  –1
                                                  а то, что «с них всё начинается»: компилятор C написан на C, компилятор C++ написан на C++
                                                  И как компилировать компилятор Си, написанный на Си? Точно таким же образом можно реализовать и интерпретатор LLVM-кода.
                                                    0
                                                    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. Уже есть несколько проектов операционных систем на нём. Я думаю, уже само их существование сбивает Ваши доводы с ног.
                                                      –1
                                                      «с них всё начинается»: компилятор C написан на C, компилятор C++ написан на C++

                                                      Turbo Pascal написан на Pascal, Javac написан на Java…
                                                      Я не понял Ваш аргумент, поясните, пожалуйста. Что значит «с них всё начинается»?
                                                        0
                                                        Человек хотел, наверно, сказать, что C и C++ чаще всего используются в качестве нулевого компилятора для языка.
                                                  +7
                                                  Эмм, может мне кажется, но больше всего непрофессионализм выдает именование «сишка»
                                                    –7
                                                    Конечно! А ещё больше непрофессионализм выдаёт фон моей аватарки. Вы такие забавные :3
                                                      +5
                                                      Я думал-думал и я все понял. Классика троллинга (толстого), описанная еще на лурке. Приходишь в пост о С++, говоришь что с++ это хрень, ну и т.д. Эх, классика
                                                    +1
                                                    И какие преимущества у сишки по сравнению с плюсами?

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                                                                                            Но это на самом деле еще раз доказывает, что C++ более чем гибкий (и у него есть фантастические компиляторы).
                                                                                        0
                                                                                        И на самом деле быстроту и производительность даёт (или не даёт) по бОльшей части именно этот преобразователь из вашего любимого языка в машинный.
                                                                                        Компиллятор тоже в некоторой степени ограничен
                                                                                        * Если у вас динамически типизируемый язык, то вам потребуется больший оверхед на поддержку этого счастья. Тут никуда не деться.
                                                                                        * Если у вас есть счетчик ссылок и сборка мусора, то вам потребуется рантайм, чтобы все это дело обсуживать. С другой стороны, у вас больше возможностей по оптимизации структуры памяти и, возможно, меньшее число копирований памяти.
                                                                                        * Если у вас компиллируемый в некоторые модули язык, то вы не сможете провести межмодульную оптимизацию (нельзя заинлайнить вызов функции из другой динамической библиотеки, ничего не поделать)
                                                                                        * Если у вас компиллируемый в машинный код язык, то вы всегда будете компиллировать под некоторую обобщеннцю платформу и не сможете применить некоторые платформозависимые оптимизации.
                                                                                        * Если у вас компиллируемый в машинный код язык, вы не сможете код в рантайме его оптимизировать в соответствии со статистикой использования
                                                                                        –9
                                                                                        Какая грустная у него фамилия. :(

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

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

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

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

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

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

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

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

                                                                                                              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

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

                                                                                                              Недавно мы тут с камеры в реальном времени 3d объекты отлавливали. В этом конкретном редком примере плюсы нужны, согласен. Но они чистые, без objc.
                                                                                                                0
                                                                                                                Дело было так — приложение клиент-серверной архитектуры, где сервак делали китайци по заказу шведов, обновления для локальной базы на девайсе клиента обеспечивала выкачка некоего файла с текстом до 8 мб с полученого в респонзе на реквест юрл. Файл засорен разнобойной служебной информацией которая нам по сути не нужна, не имеет ничего общего с json/XML. В общем предстояло изобрести мега велик — так вот попытка использовать парсить строки стредствами foundation не выдерживала никакой критики по перформансу, все эти чарактерсеты, и прочие проверки на наличие префикса и суффикса были ужастны, кроме того в словарь часто попадали принятые за корректные данные обрывки служебной информации с крякозябрами (NSString он в любой кодировке NSString), а вот чтение файла простейшими средствами С++ возомело эффект на выходе мы имели стройные UTF8 строки, из которых было очень просто выбросить мелкие изьяны, правда я проиграл на скорости чтения файла (+30%), но скорость парсинга удалось сократить в 4(!) раза.
                                                                                                    0
                                                                                                    Работаю в Google. C++11 в полный рост. Кроме мест где надо очень высокая переносимость (C++98) — клиенты.
                                                                                                      0
                                                                                                      аналогично Blackberry
                                                                                                      0
                                                                                                      пользуйтесь C++/CLI — какие проблемы?
                                                                                                    0
                                                                                                    Читал и ностальгировал, труд (язык, книги...) Берна дал мне работу(6 лет на плюсах) и крышу над головой. Я слышал как ругали плюсы мои коллеги, но я не когда не видел в них плохого. Плюсы прекрасно справлялись со своей задачей. Но к сожалению ушел от них в веб, рынок провинции диктовал свои правила жизни.
                                                                                                      +3
                                                                                                      Кто бы в Бьярну передал вопрос?
                                                                                                      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++ можно описать как историю затыкания дырок в абстракции строк. Уж не знаю, отчего бы не добавить к языку элементарный класс строчек /Джо Спольски/
                                                                                                        0
                                                                                                        передайте этому поляку что уже давно std::string or std::wstring
                                                                                                          0
                                                                                                          Да свои классы строк с бриджем и куртизанками имеет чуть-ли не каждая вторая сборка библиотек для С++, может имеется виду что всех проблем в стандартной поставке так и не решили?
                                                                                                            0
                                                                                                            Да это не поляку нужно.
                                                                                                            Дикий разгул самописных строчек уважаемых библиотекарей заставляет стонать, а отказаться от них нельзя.
                                                                                                            А строчки надо было в С++ изначально закладывать ещё при создании.

                                                                                                        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                                                                        Самое читаемое