Когда-то давно я наткнулся на статью одного МГУ'шного деятеля (Алексея Борескова) - “За что я не люблю С++” , которая вызвала целую волну праведного гнева с моей стороны - “Как же так? Да как он посмел наехать на мой людимый С++?”. Ну покипятился немного, с кем не бывает? Молодой был ещё... Однако совсем недавно судьба снова вывела на этот сайт, и освежив в памяти все указанные там тезисы, я понял — ответу быть! Ответ написан в стиле “безумцы в атаке”, поэтому не стоит ждать стройности изложения. Чуть-чуть юмора, чуть-чуть фактов, чуть-чуть философии и чуть-чуть Питона. Да-да, чтобы мыслью по древу не растекаться и было больше конкретики, я выбрал именно этот язык для сравнения с C++.

Суть терзаемого опуса сводится к тому что в С++ де всё что есть всё плохо, и Страуструпа надо жечь на костре. При этом автор смело обличает и срывает покровы, не удосуживаясь привести хоть какие-то факты (именно факты а не субъективные ощущения). Если выбрать самые козырные «разоблачения», то получится весьма интересная подборка. Начнем?

Когда-то давно я наткнулся на статью одного МГУ'шного деятеля (Алексея Борескова) - “За что я не люблю С++” , которая вызвала целую волну праведного гнева с моей стороны - “Как же так? Да как он посмел наехать на мой людимый С++?”. Ну покипятился немного, с кем не бывает? Молодой был ещё... Однако совсем недавно судьба снова вывела на этот сайт, и освежив в памяти все указанные там тезисы, я понял — ответу быть! Ответ написан в стиле “безумцы в атаке”, поэтому не стоит ждать стройности изложения. Чуть-чуть юмора, чуть-чуть фактов, чуть-чуть философии и чуть-чуть Питона. Да-да, чтобы мыслью по древу не растекаться и было больше конкретики, я выбрал именно этот язык для сравнения с C++.

Суть терзаемого опуса сводится к тому что в С++ де всё что есть всё плохо, и Страуструпа надо жечь на костре. При этом автор смело обличает и срывает покровы, не удосуживаясь привести хоть какие-то факты (именно факты а не субъективные ощущения). Если выбрать самые козырные «разоблачения», то получится весьма интересная подборка. Начнем?

“Также хотелось сделать язык таким, чтобы компилятор мог сразу же находить все возможные ошибки...”

Все ошибки в программе найти невозможно — это не под силу ни человеку (поверьте мне как опытному тестировщику), ни автотесту (поверьте мне как опытному автотестеру), ни тем более компилятору (поверьте мне как опытному программисту, хе-хе)) вот такой я спец во всём ). Знал ли это Бьярн? Да знал. Потому что дураки компиляторы не пишут, и языки, становящиеся стандартом де-факто в промышленности, не создают, а следовательно он был умным человеком. Речь шла об ошибках, которые реально под силу распознать компилятору. Не найден метод в базовом классе? Получите ошибку. Неправильно написали if? Пожалуйста — ошибка в строке N. Вызвали метод с неправильными параметрами? Вот он мерзавец. Причем это все на этапе компиляции. Что это значит в боевых условиях? Это значит, что не надо для отладки запускать тестовый стенд на котором вылезет эта ошибка. Не надо подкладывать какие-то сложные тестовые данные. А просто перекомпилировали модуль и порадовались жизни. В Питоне все несколько иначе, например такая косячная программа будет корректно работать:

def f():

    print "f()"

 

if 0 == 1:

    f( 1 , 2 , 3 )

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

“Только вот как понимать ОО - я не думаю, что программисты, пишущие на Smalltalk'е, сочтут С++ объектно - ориентированным языком.”

Да программисты на Смоллтоке есть истина в последней инстанции. Уж если они говорят что C++ говно, то значит так оно и есть )). Но мы-то не гордые, «стрёмности» C++ стыдиться не будем, а продолжим не смотря ни на что писать программы и зарабатывать на этом денюжку.

“А как дела у С++ с интеграцией со скриптовыми языками - Perl, Python, Tcl, Ruby и др?”

Про интеграцию с Питоном ответственно заявляю — все работает очень резво, что называется с адским свистом. Аж уши закладывает ). Класс для работы с питоновскими скриптами был написан за 1 день. Причем даже не написан а «нарисован», другого слова подобрать не могу, ибо так все красиво получилось.

“А вот Python умеет легко работать даже с такой кривой объектной моделью как СОМ...”

Блин, ну тут даже не знаю что сказать. Может Борескову это и не известно, но C++ тоже может работать с COM.

“Кроме того, С++ вообще не различает два существенно РАЗНЫХ понятия - абстрактнывй тип данных (АТД) и объект.”

Тут видимо автор дюже сильно разоблачать начал, наверное даже кровавая пелена глаза застлала )), уверенно заявил что объект и АТД в C++ это одно и тоже. Дайте две (цэ).

“кстати посмотрите в книге Андрея Александреску на каких компиляторах он весь код свой проверял, скорее всего вы ни одного из них просто не знаете.”

Конечно, эти компиляторы известны только Борескову, и то только потому что Александреску их по секрету сдал Борескову. Теперь они оба молчат аки партизаны и никому о них не говорят, в то время как все программисты в мире прозябают в невежестве и дикости, компилируя мелкомягким компилятором )).

“Итак, с объектной ориентированнностью получается плохо - есть какая-то странная смесь АТД и объектов (половина от одного, половина от другого), объектной модели нет вообще, основная гибкость относится ко времени компиляции.”

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

Вспомним “Вы не платите за то, чем не пользуетесь”.

А как же исключения (exceptions)”

Никто не насилует. Не нравится — не используй.

“а как же RTII ?.”

Отключается в настройках компилятора.

“а Вы знаете что в английском языке сокращение STD расшифровывается как Sexually Transmitted Deseases?”

Видимо больная для Борескова тема )).

Помнится при оформлении на военную кафедру надо было принести справку из кожно-венерологического диспансера о том что у будущей элиты Российских ВС все нормально с “размножалкой”. Ну значит пришли мы с другом в это заведение, сели на лавочку и стали анекдоты травить на тему “называем писю членом и начинаем лечить сифилис”. Нам-то пофигу - у нас все в порядке со здоровьем. А вот местный контингент юмора не оценил, люди стояли сосредоточенные и смурные. т.к. лечение проходило по схеме “Доктор, ЭТО туда не влезет! Нет больной, влезет. Снимайте штаны!” (сам то я ни при делах, мне просто рассказывали)) ). Ну значит облаяли нас, подмахнули все справки и выгнали, чтобы не раздражали пациентов )).

“Вывод по этому пункту - можно писать эффективно, но пройдет несколько лет, прежде чем Вы начнете это делать. А пока, скорее всего, об эффективности можете забыть.”

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

“Простейшим примером ситуации, когда у в Вашей программе на С++ может потечь память является автоматическое создание (и их вызов) операторов присваивания и copy-конструкторов.”

Простейшим примером ситуации, когда в Вашей программе на Питоне может потечь память является образование циклических ссылок. Что? Есть модуль gc? Хм, тогда похоже вы знаете толк в извращениях.

“Мне как-то пришлось искать почему программа, написанная аспирантом ф-та ВМиК МГУ падает через пару недель работы (она должна была работать на сервере месяцами). Именно по этой самой причине - копирование и уничтожение объектов при хранении объектов в контейнерных классах.”

Ну что можно сказать? Этот человек не прошел бы собеседование со мной )).

“Конечно это лечится :))) - нужно написать правильные copy-конструктор, оператор присваивания и декструктор.”

Борескову видимо опять неизвестно, что правильно надо писать не только перечисленные функции а вообще все функции в программе. Хотя конкретно с этими четырьмя функциями можно схитрить – на определенном этапе написания программы можно вообще забыть про конструкторы/деструкторы/присваивание, т.к. компилятор создаст их сам, причем сделает это абсолютно корректно. Вот что имею ввиду:

class A{ 

public:

    A( void )

    {

        std::cout<<"A::A( void )"<<std::endl;

    }

    A( const A & a )

    {

        std::cout<<"A::A( const A & a )"<<std::endl;

    }

    ~A()

    {

        std::cout<<"A::~A()"<<std::endl;

    }

    A & operator=( const A & a )

    {

        A tmp;

        std::cout<<"A & A::operator=( const A & a )"<<std::endl;

        return( tmp );

    }

};

  

class B{

public:

    A a;

};


int main( int argc , char * argv[] )

{

    B b1;

    B b2( b1 ) ;

    b1 = b2;

    _getch();

    return( 0 );

}

Для класса “В” не определено ни одного конструктора/деструктора/оператора присваивания, все сгенерировал компилятор, на основании вызова соответствующих методов полей, если быть конкретнее, то объекта “а” класса “А”. Причем все работает корректно.

“Но оказалось, что выпускник ВМиК МГУ (работающий в программистской фирме) этого не сделал. И на клинического дебила при этом не похож.”

Да, точно, такие ошибки будучи в аспирантуре только одноклеточные совершают. Или блатные.

“Известных консультант по ООП, Алистер Коберн в своей книге “Surviving object-oriented projects” считает, что при отсутствии значительного опыта “С++ представляет собой наиболее серьезный технический риск для выживания проекта”. И призывает не надеятся, что программисты на С смогут легко перейти на С++.”

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

“Ему принадлежит следующее высказывание - “Легче научить программиста на С Smalltalk'у, чем С++”. Подумайте об этом, этот человек видел и консультировал очень много проектов.”

С горы всегда проще катиться вниз, чем взбираться на неё.

“И при всем этом компилятор зачастую не ловит даже простейших ошибок.”

См. выше.

“Боле того, оказывается, что компилятор в ряде случаев не ловит даже такую ошибку, как лишние параметры. Известен случай, когда в библиотеке векторов для обозначения скалярного произведения переопределили оператор ','.”

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

“Причем, что самое главное, компилятор в принципе может обнаруживать лишь ошибки в структуре языка. В то время как набор тестов способен определять ВСЕ ошибки.”

Да нет не все, а только ошибки в тех текст-кейсах, которые тестировались. Однако проблема не в автотестах. А в стоимости их написания. Я уже рассказывал о том, как можно проводить автотестирование в «экономном» режиме. От автотестирования GUI придется либо отказаться, либо потратить на это огромные деньги.

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

“Однако в случае многонитевых приложений подобная политика запросто приводит к возникновению т.н. raise condition, например, одна нить может уничтожить одну переменную, а другая - что-то записать в нее. При этом сущесвтует вероятность того, что произойдет обращение к уже освобожденному блоку памяти и падению программы.

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

Очень интересно как эта проблема решена в Objective-C. Но автор почему-то нам не рассказал об этом.

“А как правило, каждый раз, когда Вы используете класс map, для него заново генерируется код и включатся в выполнимый файл.”

Не всегда. Только тогда, когда шаблон инстанциируется новым типом.

“А как Вам очень распространенное предупреждение компилятора в VC 6 о том, что длина идентификатора превысила 255 символов?”

Лично мне пофиг.

“При этом следует иметь в виду, что все эти встроенные классы и методы для работы с ними были написаны на чистом С и сильно соптимизированы, поэтому скорость работы может в ряде случаев оказаться даже выше чем у эквивалентной С++ программы (при несравненно меньшем объеме кода).”

Почему-то автор опять не снизошел до демонстрации примеров. Так же очень хотелось бы посмотреть во что обходятся все самые вкусные фичи Objective-C, которые так фанатично пиарит Боресков. Чудес не бывает, как бы эльфам из страны цветов этого не хотелось бы.

“А возврщаеясь к скриптовым яызкам - там почему-то все очень легко и просто, и внутри всего лежит именно reference counting.”

Причем подсчет ссылок абсолютно не работает с циклическими ссылками. Но их обрабатывают другие более сложные алгоритмы, которые работают в разы медленнее. Что же нам делать? Побежим покупать дополнительную планку памяти?

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

Ладно, пора закругляться. В заключении оговорюсь, что статья была написана не для того чтобы “закозлить” Борескова, и тем более не для того чтобы закозлить Питон, который является очень хорошим языком (по моему сугубо личному мнению). А для того чтобы показать, что все программы создаются с оглядкой на индустрию, на программистов, на существующие машинные мощности. Что всегда будет сделка между желаемым и дествительным. И что никогда, ни при каких условиях не будет все хорошо в мире промышленного программирования (да и вообще в мире человеческом). Всегда будет борьба насмерть, из которой выйдут победителями только Мастера. Те кто сможет почувствовать, понять и принять слабости выбранного языка программирования. Ибо только осознание собственных слабостей заставляет ярче сиять нашу силу, определяющую победителя в вечной борьбе. Силу, которая, соединяясь с мастерством, превращает программиста в Демиурга. Те кто не смогут этого понять, будут быдлокодить за еду и метаться в панике при выходе каждого нового фреймворка, но победителям до них не будет никакого дела...