вторник, 23 декабря 2014 г.

[prog.c++] Хорошая серия статей Б.Страуструпа "Five Popular Myths about C++"

Уже давал ссылки на эти статьи в G+, но по завершении серии имеет смысл собрать их все вместе:

Part 1.
Part 2.
Part 3.

Статьи на английском, но читаются легко (хотя, может это я уже привык к стилю изложения Б.Страуструпа).

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

А вот тем, кто про C++ знает лишь из нескольких лабораторных работ в ВУЗе и страшилок, рассказываемых на профильных форумах, смысл прочитать весь цикл есть. Нынешний C++ -- это не так модно и молодежно, как Erlang, Scala или Haskell. Но, скажем, по сравнению с мейнстримовой Java современный C++ обладает потрясающей гибкостью и выразительностью. А по сравнению с модными динамически-типизированными языками, вроде Ruby или Python, просто совершенно другой скоростью исполнения кода.

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

Хотя тут нужно оговориться. C++ в настоящий момент применяется в настолько широком спектре прикладных ниш, что использование C++ во встраиваемых системах жесткого реального времени, где запрещены new и throws, самым кардинальным образом отличается от ММО-игр или соцсетей масштаба Facebook. Плюс успешность разработки на C++ будет сильно зависеть от наличия готовых инструментов для вашей предметной области: если таковые есть, то работа на современном C++ немногим сложнее, чем на Java или Ruby.

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

Кстати говоря, при разработке инструментария на современном C++ вы вряд ли часто будете сталкиваться с проблемами управления памятью, основными страшилками, которыми пугают новичков "эксперты". В последние годы лично мне крайне редко доводилось ловить баги, связанные с утечками или расстрелами памяти, или с обращениями по повисшим указателям. Опять таки, это определяется качеством имеющегося у вас инструментария. Может, если вы все делаете вручную на самом низком уровне, не пользуясь вообще ничем, даже STL-ем, то утечки и повисшие указатели -- это ваши обычные спутники. Однако, если речь идет о широком использовании таких инструментов, как Boost, Qt, ACE и/или POCO, то ситуация будет совсем другой.

А вот с чем действительно сейчас приходится бороться при разработке на C++, так это с самыми высокоуровневыми возможностями -- с шаблонами. Поскольку язык настолько мощен и гибок, что позволяет воплощать в жизнь самые разные фантазии разработчика. И это все при полном контроле за типизацией во время компиляции и высочайшей скоростью работы сгенерированного кода. Вероятно, сторонники Haskell-я читая эти строки иронически ухмыльнутся, мол про какую-такую статическую типизацию и контроль со стороны компилятора можно говорить в C++! :) Может они и правы, в Haskell-е я не копенгаген. Однако, если сравнивать с Java или C#, то возможность в C++ сделать вот так:

// Ничего не возвращает.
// Т.е. send имеет формат: void send(to, traits, what);
//
send(handler, message_lifetime(10ms) + registered_delivery(*this), request);

// Возвращает std::future<reply>.
// Т.е. send имеет формат: future<reply> send(to, traits, what);
//
send(handler, message_lifetime(10ms) + result_by_future<reply>(), request);

// Возвращает reply.
// Т.е. send имеет формат: reply send(to, traits, what);
//
send(handler, message_lifetime(10ms) + result_by_value<reply>(), request);

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

Так что серия статей реально хорошая. Как раз для тех, кто по-незнанию привык объединять C и C++ во что-то древнее, страшное, глючное и непонятное под общим названием C/C++ :)

Комментариев нет: