C++

Материал из Lurkmore

Перейти к: навигация, поиск
Kapitan ochevidnost'.jpgCaptain Obvious to the rescue!
Сия статья создавалась при активном участии Капитана Очевидность, в результате чего она пространно повествует о вещах, достаточно полное представление о которых имеет даже младенец-имбецил. Так-то!
«

There are just two kinds of languages: the ones everybody complains about and the ones nobody uses.

»
— Bjarne Stroustrup
«

На говне сметану не сделаешь

»
— Народ о Qt для C++
b
Типичный программист на C++

С++ (си-плюс-плюс, си два плюса, cpp, кресты, плюсы, сипипи, цепепе, приплюснутый, ци с классами, The Programming Language) — язык программирования, который за минимальными исключениями знаком всем программистам, но которым пока никто полностью не овладел. Создан Страус-трупом с целью поднять зарплаты специалистов в индустрии, что, судя по всему, ему успешно удалось, так как по сложности изучения С++ превосходит все остальные промышленно используемые языки программирования вместе взятые[1].

Первоначально представлял собой C + ООП + тележка разных прелестей. Ныне же, со всеми доработками и библиотеками, абсолютно всеобъемлющ, поэтому, предположительно, является языком, на котором Б-г написал Вселенную. Реализует все парадигмы, включает в себя все технологии, годен для любых целей. Несмотря на это, продолжает эволюционировать. При этом быдлокодеры находят в нём простоту и ясность, а гуру-программеры — сложность и глубину. Правда, ровно до тех пор, пока не увидят чужого кода, который, как правило, отличается от их собственного так же, как они сами от автора того кода.

Чудо-оружие эпохи технофашизма, о чём громко говорит имя описывающего его стандарта: ANSI ISO/IEC 14882:1998. Самый новый стандарт называется C++14 или ANSI ISO/IEC 14882:2014. Всё это безусловно доказывает безграничную многоликость Языка и выявляет его божественную природу, что некоторыми неверными интерпретируется как воплощение вселенского зла.

Содержание

Как же так вышло

«

Не вызывай strlen в контексте строки его!

»
Дейкстра

Сначала где-то в 60-70-х как развитие структурного программирования была придумана ересь под названием ООП. Уже тогда великий Дейкстра прочуял пиздец и отозвался о ней как об «исключительно плохой идее, которую могли придумать только в Калифорнии», но сделать ничего не мог, так как туча мозгоблудов тут же эту идею подхватили. Следствием этого стали многочисленные языки программирования, реализующие задумку. В начале 70-х гении, чьи имена нельзя упоминать всуе, создали Юникс и Це. Первое навсегда стало лучшей осью для серьёзных машин, а второе — языком, на котором эта ось написана и лучшим языком для системного программирования.

В начале 80-х некто Страуструп решил улучшить лучший язык программирования, а также поднять свое ЧСВ до уровня K&R, заодно за счёт троллинга студентов, которых начали дрессировать именно на этом сабже, и это тот самый сабж который они знают и ненавидят больше всего. Так как на слуху тогда было именно ООП, то он решил прикрутить к лучшему языку для системного программирования ООП, да так, чтобы получившийся гибрид был быстр и совместим с Це. Ему удалось. Почти. К сожалению, полная совместимость достигнута не была.

Когда Р-чи хотел внести в C очередную фичу, К-рниган говорил: «Если тебе нужен PL/1, ты знаешь, где его взять.» Видимо, Страуструп не знал, где взять PL/1. В общем получилось так, что на продвинутый ассемблер накрутили продвинутое ООП. Это типа как бомжа не помыли, а надели фрак, а потом еще и корону.

Но всем было б похуй, если б в тех же 80-х в мировой прогресс не вмешались ИБМ со своими персоналками. Внезапно, вместо однородных блоков числовых данных программам стало необходимо обрабатывать пёстрые массы офисной инфы, причём чуть ли не каждый кусочек её имел своё множество допустимых значений и требовал особого обхождения, что в переводе на компьютерный матан означает, что каждый такой кусочек имел свой тип данных. Когда же в начале 90-х на экранах персоналок замаячили окна и от программ потребовали ещё и гуёв, то профит от использования ООП стал очевидно прогнозируемым. С учётом невысоких тех. характеристик тогдашних машин, наиболее удачным решением выглядел переход на С++. Что и было массово осуществлено всей индустрией.

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

Великий Поход II

«

Ты уверен, что ты писал на C++, а не на C с классами?…

»
RSDN

Здесь должен быть текст про MFC, но погромистов под MFC осталось так мало (сошли с ума, десу), что и рассказывать-то некому. В общем, это был неправильный Ц++ и он ушёл от нас.

А вот недавно вышедший стандарт C++11 (gcc, clang, microsoft visual studio уже собирают, так-то) порадовал ключевым словом «auto» (привет, «var» из C#) и лямбдазамыканиями. Да-да, элементы функциональщины теперь и в моём C++.

Под *nix-ами С++ уверенно отбивается от Явы, а ещё летает в космос и пикает в чипе карточки метрополитена[ЩИТО?].

Под Виндой существует в Visual Studio, где стараниями мелкомягких сделался C#-подобен: арифметика указателей по умолчанию оторвана, компилируется в IL-код для .Net. Но можно собирать и простые, не .Net-овские exe-шники.

Отставшим от жизни олдфагам новый стандарт ничем не угрожает, «потому что пока примут, пока появятся компиляторы, пока рак на горе свистнет». Но Анонимус уже в курсе, что поддержка тех же лямбд и потоков есть уже практически везде, и gcc и clang поддерживают новый стандарт целиком, а их стремительно догоняют Microsoft C++, Intel C++ и IBM XLC++ (да! есть и у них свой компилятор!). И C++Builder тоже реабилитировался и нечастыми, но уверенными шагами, приблизился к конкурентам.

Веб-дизайнеры его, ес-но, не знают и не хотят знать.

Рассказ подрывника


Что же дальше


Хелловорлды

Бульк


Шаблоны

Десятое правило Гринспена гласит: «Любая достаточно сложная программа на C или Фортране содержит заново написанную, неспецифицированную, глючную и медленную реализацию половины языка Common Lisp». Шаблоны являются таким недолиспом, встроенным в язык C++.

Шаблоны.они (

  • Полны по Тьюрингу.
  • Вычисляются на этапе компиляции, что с учётом первого преимущества позволяет добиться сколь угодно долгой сборки программы.
  • Круче дженериков, что является важным аргументом в спорах C++ кодеров с их коллегами, пишущими на Java или C#.
  • Позволяют в полной мере реализовать обобщённое программирование, функциональное программирование, объектно-ориентированное программирование, в общем все парадигмы, которые С++ как бы реализует.
  • Круче макросов. Что оспаривается любителями C. Любители С++ же используют и то и другое в одном месте, и им мало.
  • Boost состоит из шаблонов чуть более чем на семь четвёртых.
  • STL состоит из шаблонов чуть менее чем полностью. (спойлер: Cтандартная библиотека шаблонов состоит из шаблонов чуть менее чем полностью)

);

Примеры


STL

Это была идея Вирта, что «Алгоритмы + структуры данных = программы».

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

В качестве структур данных выступают контейнеры, такие, как массив, список, словарь, а в качестве алгоритмов — сотня какой-то непонятной хрени вроде lexicographical_compare и set_symmetric_difference.

STL.он (

  • На 3,1415926535897932384626433832795% реализуется разработчиком компилятора (из-за расовых разногласий ОС), поэтому существует десяток реализаций, каждая со своими клопами.
  • Содержит разрыв шаблона. Нормально, шаблон vector<T> — контейнер STL типа вектор, содержащий T. Но vector<bool> — ни разу не контейнер STL и никаких bool не содержит. Но всем абсолютно похуй, взамен юзают vector<char>.
  • Множества и словари в STL сделаны не на хеш-таблицах, а с применением деревьев поиска, что обычно печально с точки зрения производительности (есть версии, реализованные на хеш-таблицах, нужно просто добавить префикс hash_ или unordered_).
  • Громоздкое в использовании API из-за стремления к максимальной общности. Например, для получения значения по ключу из ассоциативного массива (без потенциального изменения состояния последнего) необходимо написать байт 200 кода. Для кого-то лечится макросами вроде BOOST_FOREACH и RANGE.
  • Вызывает привыкание:
STL … It’s also something that, when you first encounter it, makes you wonder what the hell the designer was smoking. And once you’ve gotten used to it, you start wondering why other library designers don’t start smoking the same thing.

);

Итоги

По мере своего старения и уменьшения головного мозга, Александр Александрович полностью разочаровался не только в C++, но и в объектно-ориентированном программировании вообще. Вот что он пишет про ООП:

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

Пруфлинк: «Почему объектно-ориентированное программирование провалилось».

CUDA и OpenCL

для тех, кого забанили в педивикии: OpenCL != OpenGL ; OpenCL != OpenML ; OpenCL != OpenAL

Матановые библиотеки, позволяющие получить на C++ ещё больше скорости, так как вместо медленного центрального процессора задействуют графический процессор или другой вычислительный ускоритель. Возможно использование комбинаций графических ускорителей, однако NVidia SLI в силу конструктивных особенностей не работает с CUDA.

Своим появлением обязаны развитию графических шейдеров, изначально представлявших собой коротенькие инструкции для операций с текстурами (типа сложить текстуру A с текстурой B). Со временем сложность шейдеров нарастала, позволяя реализовывать более сложные операции, а помимо текстурных шейдеров появились вершинные шейдеры — для изменения координат вершины треугольника[2]. В общем, компьютерная графика развивалась, и по вычислительной мощности[3] графические процессоры превзошли центральные процессоры общего назначения.

Затем появился PhysX — специализированный процессор для работы с физикой, на которую ранее в компьютерных играх тупо забивали болт. Этот процессор превосходил по своей мощности центральные процессоры общего назначения, так что при воспроизведении какого-нибудь физического эффекта центральный процессор тормозил, а PhysX показывал невозможное. Но был один минус: физический ускоритель PhysX стоил ощутимых денег, и потому многих начала так же ощутимо душить жаба, при том что далеко не все игры поддерживали новые физические спецэффекты, и получалось, что недешёвую карту физического ускорителя нужно покупать, чтобы узреть красоту в 3,5 играх при отсутствии какого-либо другого влияния на игровой процесс (второй Half-Life с его гравитационной пушкой ещё не появился).

И пока хомячки пищали, но готовили свои кошельки… вдруг эсперты выяснили, что несложные физические вычисления, типа сложить пару-тройку векторов, можно выполнить и через вершинный шейдер, а если извернуться, то можно посчитать физику и на текстурных шейдерах. Правда, всё это с бутылочным горлышком перегонки массивов данных из обычной памяти в графическую и обратно с участием центрального процессора. В общем, радужные перспективы PhysX, стали для специалистов и экспертов тускнеть и становиться туманными, в то время как для обычных хомячков, «эффективных» менеджеров с их гуманитарным образованием, и биржевых трейдеров, торгующих акциями, перспективы продолжали казаться такими же радужными… => его создатели постарались его побыстрее продать, пока не упали акции, а nVidia постаралась его побыстрей купить, пока это не сделали конкуренты. В итоге nVidia:

  1. включила все наработки PhysX в свои видеокарты,
  2. переделала текстурные и вершинные шейдеры в шейдеры общего назначения,
  3. запилила CUDA, а затем и OpenCL, позволяющие считать произвольный матан на шейдерах общего назначения.

WIN!

Boost

Как забыть C++

В некотором царстве, в некотором государстве, два C++ программиста, приняв пару стаканов вина, обсуждали разработку открытых библиотек, которые должны были бы содержать всё необходимое, не включенное в недавно вышедший Стандарт. Один из них упомянул, что Герб Саттер готовил пропозицию языка программирования Booze, который должен был быть лучше, чем Java. Смысл этой остроумной шутки в том, что java — сорт кофе, а booze — «бухло». Продолжением игры слов стало название «Boost» для набора открытых библиотек, куда на сегодняшний день вошли около сотни библиотек, а некоторые из них даже были запилены в нынешний или будущий Стандарт (пруфлинк — FAQ буста).

Использование этого набора библиотек в промышленном коде является предметом споров, причём не только в форумах интернетов, но и IRL с заказчиком, начальником или коллегой. Консерваторам не очевиден профит применения проверенных решений вместо написания своих велосипедов, также их пугает размер и сложность буста. На первый взгляд, опасения кажутся небезосновательными — эта штука собирается полностью около часа на не самом слабом ПК и занимает несколько гигабайт в собранном виде со всеми либами во всех конфигурациях; многие библиотеки кажутся полными матана и возникают сомнения в способности быдлокодеров использовать их. На самом деле, вышеприведенные опасения — хуита, а поддержка своих велосипедов или написание «минималистичного» кода обходятся дороже.

Qt

Ещё в 90-х двое троллей решили подшутить над владельцами тёплых ламповых машинок, и показать миру быстрый и лёгкий GUI. В итоге была организована компания w:Trolltech, и их детище — Qt получило неиллюзорный коммерческий и просто народный успех. Позже это всё богатство было продано Nokia, затем перепродано Digia, в свете анальной связи Nokia с Microsoft. Алсо «Qt developers are happy developers. 95% Satisfaction.» (c) www.qt.io

Достоинства

  • Кроссплатформенность и кол-во фич как у жабы.
  • GUI можно строить покрасивее, чем в дэльфи и прочих — есть даже поддержка CSS, HTML и даже пародия на JavaScript, в виде w:QML.
  • Весьма и весьма шустрая и небольшая библиотека.
  • Сигналы и слоты.
  • Имеются порты на десятки языков.
  • Одна из основных сред слюникса.
  • Полноценный фреймворк, даже есть пародия на GC (все объекты наследующие QObject удаляются автоматически).
  • Парадигма MVC, ограждающая вменяемых программистов от быдлокодеров[4].

Недостатки

  • Несмотря на простоту, школьникам всё равно не даётся.
  • Нужно полное понимание ООП, из-за чего школьникам и быдло/C-кодерам не даётся.
  • Зависимости: если решил внести в софтину новую функциональность — нужно пересобирать всю библиотеку (если же распространять «как есть» — вес библиотек составляет почти 30мб).
  • На нищебродских машинках тормозит, ибо слишком широк и создан без понятия цели создания.
  • В версиях до 4.* все кнопки, полоски просмотра и прочие элементы окон рисовались везде одинаково (и везде одинаково убого), начиная с 4 под каждую систему всё прорисовывается как нативное.
  • Moc компилятор.
  • Был создан, как легковесная графическая библиотека, а превратился в широкий глобус с чуть менее видными краями.
  • Сборка под виндами — весьма тоскливое занятие.
  • Qt Creator и плагины для прочих IDE могут в один прекрасный день перестать видеть qmake.

Где он живёт

В наши дни C++ программисты по-прежнему очень нужны. Когда такого программиста удаётся поймать, его сажают за компьютер и заставляют:

  • Поддерживать стародавный С++ (а то и Pure С) код.
  • Писать большие коробочные игры (куча готовых движков/библиотек плюс быстрота)
  • Задрачивать системное/низкоуровневое программирование (драйвера, работа с портами и т. п.)
  • Писать ядро высоконагруженных систем, для которых Java слишком требовательна, а Erlang тормознут. Apache, например. Или Dropbox.
    • Высоконагруженные ядра облачных вычислений, как и требовательные к быстродействию приложения на стороне клиента. И здесь C++ вновь зохабал новый рынок под себя.
  • Писать ядро приложения, которое обрамляет код на более простом и понятном языке. Всякий научный и узкоспецифический софт вроде Mathematica.

Разумеется, адекватные программисты пишут на C++ только основные части, самые требовательные к нагрузкам и памяти. Для интерфейсов, внешней логики и прочей функциональщины используют внешние языки (Lua, Ruby, Boost:Python), которые милосердней к пользователю. А то и вовсе компилируют код в библиотеку и подключают к своему уютненькому проектику на PHP.

А вот всякий интерпрайз и корпоративные приложения выбирают Java и C#. Для них C++ решительно не подходит:

  • Сложен и настроить в нём можно всё. За счёт этого не помещается в голове даже у самого Страуструпа.
  • Чтобы работать стало легко и приятно, надо осилить STL/Boost. А про них в учебниках пишут редко и скомкано: большинство программистов до сих пор учится по книгам, которые описывает не столько C++, сколько именно C с классами. Желающие писать на C++ крутотень и зарабатывать OVER9000 баксов должны узнавать что-то новое каждый день и неустанно постигать библиотеки (начинаешь с книжки 21st Century C: C Tips from the New School и далее по нарастающей)
  • Крайне сложная формализация. Поэтому в то время, как под Python/Java/C# есть ReSharper, который находит очепятки в коде прямо на лету, на C++ приходится каждый раз компилировать и распутывать запутанные ошибки компилятора, который в очередной раз подавился шаблоном. Спасибо, что подсветка синтаксиса есть.
  • Язык универсален — а веб-морду всё равно не сделаешь. Конечно, есть WT, но без сборки мусора пыхтеть придётся долго.


Писать большой проект с нуля и на C++ заслуженно считается малоудачной идеей. Любой программист прокачавшийся выше хеллоувордщика допускает на 10 000 строк кода примерно одинаковое количество ошибок (которое варьируется от 1 у Кнутов и Кормаков до 10 000+ у типичного быдлокодера). А код на C++ обычно длиннее, чем на более поздних языках, и багов, разумеется, будет намного больше. В разы проще написать пусть медленный, но макет на чём-то хоть и медленном, но со сборкой мусора (обычно это C#, Java или Python, т.к. умеют читать C++-библиотеки), а потом переписать особенно тормозящие участки (которые, как водится, окажутся совсем не там, где ты думал). Наконец, бывает так, что единственная скорость, которой хочет заказчик — это скорость разработки и он покупает макет и начинает юзать его как нормальную программу, оставляя программистов наедине с баблом и удивлением.

В результате мы имеем всякие экзотические конфигурации вроде заводского сервера для станков на MINIX (видимо, переделывали из собственной дипломной работы, вдохновлённой общеизвестной книгой Таненбаума).

А заказчик, помучившись год, начинает требовать версию 2.0, с кучей новых фич, а «скорости мне хватает». В результате макет переделывается, и снова переделывается, и снова... с перспективой превратиться в операционную систему на managed-коде, которая, в отличии от Фантом ОС, ещё и запускается.

Почему «быдлокодерский»

«

А вы друзья, как ни садитесь —
всё в программисты не годитесь…

»
— Эпос о Гильгамеше, XXII век до н.э.
Типичный представитель

Тысячи возможностей выстрелить себе в ногу в языке являются результатом совмещения высокоуровневых концепций ООП с более низкоуровневым языком С и говорят о продуманности дизайна С++ и уважении принципов обратной совместимости. Отсутствие сборки мусора говорит о попытках экономии памяти — а ещё о том, что без глобальных переменных, или как их называют теперь, «Паттерн Одиночка», программировать не получится. Зато конечный результат почему-то есть. И откуда же он взялся?…

Аргументы в пользу принадлежности C++ к «илитарным» языкам не выдерживают критики. Порог вхождения низок; как показывает опыт, каждую обезьянку, пишущую на решётках или на жаббе, можно заставить писать на С++ (хотя далеко не каждую — читать). При этом, засилье шаблонов STL и Boost побуждает гореваятелей делать даже простейшие вещи вроде сортировки данных в массиве предельно громоздкими, ресурсоёмкими и неочевидными методами.

Избыток сложности не может компенсировать низкий порог вхождения, что влечёт за собой гигабайты говнокода, кривых программ, и, как следствие наличия большого числа «типа шарящих» — низкую оплату труда письма на нём. Зачем нанимать профессионала за пять косых, если можно нанять десяток голодных студентов за пятьсот, которые хоть и наебошат говно, но зато наебошат же.

Студентами и написано на C++ относительно большое количество программ, а дописывается еще бо́льшим количеством индусов. Если системный код Windows написан на C, то свистелки и перделки, вроде IE, шелла, и прочего — чаще всего на С++. Даже мышкой херачить можно: для этого есть Видимая Студия и Борланд Ц-Быдлер. Достаточно знать 15 функций и хорошо манипулировать операторами if и while, и «программный продукт» готов.

А то, что на выходе получается АдовЪ ГовнокодЪ — никого не волнует.

Положение в современном мире

++Ↄ профессионал смотрит на тебя как на…

Серьёзный бизнес мало интересуют субъективные рассуждения школяров-задротов, наподобие изложенных выше, и поэтому на реальную роль С++ действуют совершенно иные факторы. А именно:

  1. Переусложнённость, сочетание прямой работы с памятью с грязной реализацией ООП, что для новых проектов означает увеличенный бюджет и более высокий риск фейла.
  2. Универсальность, никому, как правило, не нужная.
  3. Большой объём уже написанного на С++ кода, который приходится поддерживать. Или же кода, написанного на C и которому на кой-то хер нужно было сменить парадигму.
  4. Свежее мясо Новых программистов обычно уже не учат на этом языке (а учат этой вашей Java, C# и прочим более устойчивым к быдлокодерству языкам), и это уже вовсе не тот язык, который они знают лучше всего (а stl и boost студентота не знает чуть менее, чем вовсе).

Кроме того, если посмотреть на рейтинг популярности языков на сайте www.tiobe.com, то можно заметить две вещи. Во-первых, по популярности C++ никогда не обходил своего папу, а лишь однажды к нему приблизился, но было это в конце 90-х. Во-вторых, с появлением яблофона и яблолопаты, идейный брат C++, Objective-C, который используется почти исключительно Яблокорпорацией для их продукции и дотоле почти неизвестный, стал также набирать в популярности. И более того, в последей версии рейтинга Objective-C таки обошёл C++. Не спас даже выход C++11. Того и глядишь, через пару лет мы узнаем, почему Objective-C на самом деле непереносимо ужасный язык.

Олсо C++ практически (чуть более, чем целиком) не используется для написания этих ваших Linux Kernels & Daemons, что кагбе намекает всем нам.

И не забудьте ещё раз поправить именно эту часть статьи и донести до нас Правду!

И наконец, —



См. также

Примечания

  1. К настоящему времени кошерный способ написать что-то размером с проект на продажу на С++ — это значит написать программу на пайтоне руками джуниоров, с помощью хуёвин по имени "intermediate language" переконвертировать пайтон/что-там-у-вас-было в сабж, после чего баги ловят сениоры или же (в крупных компаниях) той же квалификации и зарплаты миддлы
  2. В современной компьютерной графике модель представляет собой многогранник из множества треугольников
  3. Если измерять в флопсах, то есть скорости выполнения операция над числами с плавающей запятой/точкой.
  4. см. w:Магическая кнопка


Источник — «http://lurkmore.to/C%2B%2B»