Почему никому не нравится язык программирования C++?

Однажды программист Дуглас Крокфорд сказал: "Только сумасшедший будет использовать C++". Так почему C++ считают далеко не лучшим языком для программирования? На этот вопрос отвечают пользователи сайта Quora.

 

Джон Харроп, занимается программированием больше 34 лет

Почему C++ считают не лучшим языком для программирования? Вероятно, объяснить подобное будет проще всего, сравнив C++ с другим языком – C, который отлично оформлен и обладает высокой функциональностью.

Особенности языка С обусловлены определенными целями. Эти особенности предназначались для решения реальных проблем и тех проблем, которые они сами могут вызвать. Простая арифметика с целочисленными операторами. Автоматическое распределение регистров с помощью портативного (между компиляторами) двоичного интерфейса приложений. Простой, но удобный процессор предварительной обработки. И многое другое. Кроме того, язык С не сильно усложнен: написать компилятор этого языка можно за достаточно короткое время (tinycc – это компилятор С для платформы х86, написанный всего за 65 тысяч строк кода C!). C был выпущен для достижения определенной цели, и он ее успешно достиг. Благодаря «чистоте» данного языка, на рынок в ускоренном темпе вышло огромное количество качественных компиляторов и уже на ранней стадии были доступны решения на уровне системы поддержки операций.

В отличие от С, у C++ никогда не было четкой цели, поэтому многие функции этого языка  добавлялись чуть ли не случайным образом. Первоначальная идея Б. Страуструпа (вместе с М. Эллис - автор книги «Справочное руководство по языку программирования C++ с комментариями») была следующей: «С – это круто, и объектно-ориентированное программирование (ООП) тоже круто, поэтому давайте запихнем ООП в С». Ретроспективно ООП было широко распространено, но при этом в большинстве случаев оно неверно использовалось специалистами. Настоящие языки для ООП, такие как Smalltalk или IO, обладают многими функциями, которых нет в C++. О

сновным свойством, в котором нуждался язык C, был, пожалуй, параметрический полиморфизм. Вместо этого C++ получил шаблоны, которые были предназначены скорее для решения нескольких совершенно не связанных между собой проблем, нежели для решения какой-либо конкретной задачи. Вскоре кто-то совершенно случайно обнаружил, что шаблоны в C++ элементарны, после чего была написана и опубликована программа (машина Тьюринга), которая вычисляла простые числа во время компиляции. Вау. Просто поразительное наблюдение, которое привело к тому, что люди несколько десятков лет пользовались далеко не идеальными шаблонами C++, в то время как существовали шаблоны, придуманные намного раньше и подходящие для решения многих проблем намного лучше (например, макросы Lisp или ML -полиморфизм). Хуже того, неверное использование этих не идеальных шаблонов привело к добавлению большего количества функций, к примеру, частичной специализации шаблонов.

По сути, случайно усложнение C++ привело к тому, что написание работающего компилятора для этого языка стало почти невозможной задачей. Например, для этого языка крайне сложно написать синтаксический анализатор. Синтаксис также имеет такие ужасающие операторы, как List <Set <int >>, которые интерпретируются как логический сдвиг вправо. Ни один из исходных компиляторов C ++ не был достаточно надежным. К примеру, во время получения степени кандидата наук в 2000-2004 гг. я сталкивался с десятками ошибок в компиляторах C ++ из GNU, Intel и SGI. Надежные компиляторы были созданы только два десятилетия спустя.

Принято считать, что C ++ - это крайне быстрый язык, но реальность такова, что C ++ будет быстрым только тогда, когда вы пишете C-подобный код, и даже в этом случае это правило будет работать только для определенных видов программ. Исходя из позиции «вы не платите за то, что вы не используете», C++ совершенно неэффективен. Идиома RAII, означающая «получение ресурса есть инициализация», вводит множество вызовов ненужных функций, которые иногда могут оказаться крайне дорогостоящими. Такие вызовы обычно требуют данные, которые в противном случае не использовались бы, поэтому эти данные сохраняются в активном использовании, увеличивая регистровое давление и снижая производительность. Механизм исключений  C ++ крайне неэффективен (~ 6x медленнее, чем OCaml). По сравнению с современными сборщиками мусора, распределение новой и удаленной информации в C++ происходит медленно, поэтому людям предлагается использовать стандартные библиотеки шаблонов (STL). Но для них заранее выделяют огромные блоки памяти, вследствие чего теряется одно из преимуществ, которое было в  языке С, а именно, эффективность распределения памяти. После этого вам рекомендуется написать ваш собственный распределитель STL, который уж точное не лучше, чем использование С. Одним из основных давно появившихся и ныне существующих преимуществ C перед современными языками является непрогнозируемое время ожидания, возникающее у сборщиков мусора.

А вот C ++ взял худшее: у него отсутствует сборщик мусора (что делает невозможным эффективное воздействие на полезные функции, например, использование функциональных структур данных должным образом), а порядок вызова деструкторов при этом точно не определен, а значит в любой момент в вашей работе может образоваться неограниченная пауза, так как невозможно заранее предугадать, когда именно будет утилизирован конкретный объект. Хотя шаблоны широко используются в метапрограммировании, их использование далеко не столь удобно, как хотелось бы, поэтому можно сказать, что C++ не предоставляет достаточно возможностей для метапрограммирования.

 

 

 

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

Язык C++ настолько сложен, что даже мировые эксперты, словно новички, допускают в нем ошибки и промахи. Герб Саттер работает в компании Microsoft, он долгое время был организатором и секретарем комитета по стандартизации ISO C++.  Во время одной из своих лекций он давал свой любимый 10-строчный код на языке C++, и кто-то указал ему на ошибку, приводящую к утечке памяти.

По моему личному мнению, новый язык программирования Rust – это то, каким должен был бы стать C++. В нем есть обобщенное программирование (generics), размеченное объединение типов данных, сравнение на соответствие шаблоне и многие другие новые функции, например, безопасность доступа к памяти без сбора мусора.

 

Акаш Патель, инженер по вычислительной технике

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

C# и Java – это ограниченные языки, и это как благословение, так и проклятие. В некотором смысле, с ними возникает много сложностей (необходимость создавать класс для простого «привет, мир!» это очень глупо, ведь есть другие языки программирования, в которых вообще не требуются классы). Но их преимущество заключается в том, что, будучи более ограничивающим, их компилятор способен поймать бОльшее количество ошибок, которые в C++  будут незаметны до того момента, пока вы не запустите программу. Или пока кто-то другой не запустит программу на другом компьютере, в другой день, в другую минуту.

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

Когда вы только начинаете изучать программирование, очень важно выявить правильный подход. В самом начале необходимо научиться выражать себя в коде, разбирать любую глобальную проблему на более мелкие, которые потом можно выразить в терминах языка программирования, вот что важно. Но изучение C++ вынудит вас с самого начала научиться в одно и то же время «жонглировать» огромным количеством непростых вещей, а именно, определить указатели, иметь дело с управлением памятью вручную, индексами, выходящими за границы массивов, ошибками компиляции шаблонов, утечками памяти и огромным количеством случаев неопределенного поведения (случаи, когда компилятор принимает код, но спецификация не определяет поведение языка. Это означает, что может случиться все, что угодно, даже если кажется, что код работает нормально. В С++ такое случается крайне часто, в то время как многие другие языки во время компиляции стремятся выявить или предотвратить подобные ошибки).

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

Я понимаю, что я не упомянул очень много крайне специфических характеристик этого языка. Проблема заключается в том, что большинство отдельных функций С++ достаточно просты (работа со специализацией шаблонов и указателями может сбить с толку поначалу, но, в конце концов, с этим можно разобраться. А вот метапрограммирование шаблонов наверняка сведет вас с ума, и это вполне нормально ;)). Главная проблема заключается в самом языке, где множество непредсказуемых ошибок, которые только иногда поверхностные, а в большинстве случаев отображаются только при запуске программы на некоторых компьютерах, или проблемы, которые могут возникнуть при попытке запустить сразу конструктор, копирующий конструктор, оператор присваивания и деструктор, чтобы удостовериться в отсутствии утечки ресурсов и в том, что все в порядке с классами.

 

Эрик Скотт, специалист в области теории вычислительных машин и систем

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

  • Насколько легко научиться писать высококачественный, простой в сопровождении и пригодный для тестирования код на C ++?
  • Насколько сложно написать безопасный и красивый код на C++?

Если сравнивать этот язык с C и Java, то ответ на оба выше приведенных вопроса будет «довольно сложно», и на это есть ряд причин. По сути, использование языка С++ в некоторой степени похоже на использование огнестрельного оружия – главное это знать  правила.

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

Многие верно говорят, что использование С++ не будет опасным или в тягость, если вы используете его правильно. Это, однако, не меняет того факта, что, метафорично говоря, работающие с С++ программисты каждый день сами ставят палки себе в колеса. Как говорят, «существует 6 способов реализовать простую задачу на языке С++, и 5 из них вероятнее всего закончатся полной катастрофой». Если программист достаточно опытен, чтобы обойти эти 5 вариантов, тогда он может написать отличный код.

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

Если программисты Java могут приблизительно разбираться в языке, а после, с ходом времени и наработкой практики, повышать свой уровень квалификации, то начинающий программист на С++, слабо разбирающийся в проекте, никогда не будет допущен на работу с ним. Кроме того, каждому начинающему стоит в обязательном порядке прочитать книгу Скотта Мейерса «Эффективное использование С++».

Все это ведет к тому, что многим командам разработчиков такие языки, как Java/C# и C, позволят выполнить проект быстрее, лучше и с меньшим количеством недочетов. Многие отдельные разработчики могут считать себя «безопасными владельцами оружия», создавая великолепные и красивые коды, написать которые можно только при помощи С++. Но, как правило, большинство людей предпочитают или полностью избегать С++, или же разрабатывать строгую внутреннюю политику в отношении того, какие функции этого языка будут использоваться в проекте, а какие нет.

 

Пол Конвэй, разработчик на пенсии, любитель научной фантастики

Я писал коды на С++ еще со времен Zortech. Я видел, как с течением времени язык все больше приукрашали. И еще в то время я понял, что с С++, как и в случае с С, необходима дисциплина по поводу его использования. Тот факт, что этот язык имеет некоторые крайне экзотические и непривычные функции, совсем не означает, что их обязательно нужно впихнуть в программу.
Что касается того, почему С++ считают настолько плохим – слушая других программистов, я понял, что существует огромное множество предрассудков касательно этого языка. Я встречал людей, которые говорили, что язык С великолепен, и тех, кто называл С++ совершенно ненужным и бессмысленным. И я не согласен ни с теми, ни с другими.

Около 15 лет назад, вскоре после того, как я присоединился к той компании, где я работаю и сейчас, мне поручили написать внутренний документ о принятии C ++. В нем я должен был изложить плюсы и минусы языка, последовательность шагов, которые должны были быть предприняты, а также рассмотреть возможные трудности (совместимость с существующей базой кода, наличие надежных компиляторов на всех поддерживаемых платформах, обучение разработчиков и т. д.) 

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

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

Тот документ отложили в дальний ящик, и там он лежит и сейчас, насколько мне известно. Почти все время с того момента я работал с собственно интерпретируемыми языками. Но совсем недавно, к моему удивлению, мне довелось поработать с базой исходных кодов, которую я не видел очень много лет. И подумать только, я увидел там большую часть кода, написанного на С++! Представьте себе, насколько я был удивлен.

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

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

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

Я думаю, основа подобного отношения закладывается еще во время обучения компьютерным наукам. Высшие учебные заведения стремятся снизить стоимость обучения за счет использования бесплатного программного обеспечения, поэтому многие программисты начинают с бесплатных и повсюду встречающихся Unix/Linux и С.

Кроме того, именно компания Microsoft создала первый компилятор С++, но я видел стойкое презрение к этой компании со стороны многих программистов, и подобным же презрением и негативом они награждали С++.

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

Версия для печатиВерсия для печати

Рубрики: 

  • 1
  • 2
  • 3
  • 4
  • 5
Всего голосов: 6
Заметили ошибку? Выделите ее мышкой и нажмите Ctrl+Enter!

Читайте также

 
Аватар пользователя savely

> А классы -- это обязательно? 

Майк, это есть в статье. Сформулируй тогда, чем лично для тебя практически код на C++ отличается от кода на C. Мне интересно. 

+3

Комментарии

Страницы

Аватар пользователя savely

> А классы -- это обязательно? 

Майк, это есть в статье. Сформулируй тогда, чем лично для тебя практически код на C++ отличается от кода на C. Мне интересно. 

+3
Аватар пользователя mike

Статью, штоле, написать?.. laugh

-3

mike пишет:

 БЕСПОЛЕЗНАЯ статья.

Журналисты, пишите о "почему никому не нравится язык русский". Толку больше.

 

точно! отвратительный перевод!!

Аватар пользователя mental

Обещать - не мешки ворочать... 

Аватар пользователя gaal

i = j * 5  C++ не C, не все так однозначно;) operator* operator=

+2
Аватар пользователя mike

Обещать - не мешки ворочать...

Мне интересно. 

Наглеете, друзья, минусы ставите. Хорошо, поясню кое-что, не всё, правда; навскидку. 

Односточные комменты, объявления по ходу блока, ВСЁ -- ТИП!, доступ к одноимённым глобалам, ссылки, инлайны, динамика new/delete (без этого вообще никак!), перегрузки, шаблоны, использование ГОТОВЫХ библиотек классов. Enough?laugh

Кто-нить задачку решил? laugh

-3
Аватар пользователя mike

О, уже первый минус!

Минус вместо вопросов очень показателен.laugh

-2
Аватар пользователя mike

gaal пишет:

i = j * 5  C++ не C, не все так однозначно;) operator* operator=

А не надо увлекаться перегрузками. Это как принародно колупаться в носу, думая, что шик.

-1
Аватар пользователя mike

Савелий, мой ответ тебя удовлетворил? Или молчание -- знак согласия?

Аватар пользователя savely

> Савелий, мой ответ тебя удовлетворил?

Да, вполне. 

Страницы