23 February 2012

GoingNative 2012 misc

Закрою все-таки несколько подвисшую тему GoingNative 2012 и чиркну пару строчек про остальные доклады.

Day 2 Keynote - Herb Sutter: C++11, VC++11 and Beyond
Довольно интересный доклад. Началось все с пафосного действа, которое было посвящено двадцатилетию VC++; с подножки этой темы Саттер попытался красиво въехать в рассказ о том, каким крутым будет следующий релиз Visual Studio с точки зрения C++ компилятора. Именно этот момент выступления Герба был крайне сомнительным, потому что поддержка Windows 8 это, конечно, очень здорово, но зачем, к примеру, врать о том, что это первый релиз с поддержкой компиляции под ARM? Да и работы по поддержке нового стандарта C++11 в Microsoft определенно забуксовали, громко заявленная поддержка всех новых библиотек из него это слишком мало на фоне отсутствия большого числа очень важных языковых фич (полной поддержки новой библиотеки не может быть в принципе без наличия тех же variadic templates).



Дальше пошли более полезные разговоры -- обсуждение новых фич C++11. Списки инициализации, auto, лямбда, умные указатели и так далее. Что вызвало у меня вопросы -- сомнительное утверждение (в контексте обсуждения умных указателей) о том, что теперь в хорошей C++ программе не должно быть открытого ни new, ни delete. Ну, насчет delete, тут я целиком и полностью согласен, но вот насчет new... В крайне навязчивой форме нам предлагается использовать метод make_shared; метода make_unique пока что в стандарте нет, но Герб пообещал приложить все усилия, чтобы устранить это досадное недоразумение.
На самом деле, резонное замечание на одной из "панелей" сделал Страуструп, сказав, что вместо того, чтобы столько времени обсуждать shared_ptr, лучше бы думали о том, как от него вообще избавиться в ваших программах. И это правда, потому что shared_ptr не очень частый гость в типичной C++ коде, а Саттер так беспокоится по его поводу в силу того, что новый API Windows 8 -- WinRT -- использует его буквально в каждом методе как суррогатный компромисс в вопросе сборки мусора, которой, как известно, нет в C++. В силу этого, в Microsoft сильно болит голова по поводу этой штуки, и они рассматривают make_shared как способ для оптимизации, когда разделяемое тело указателя и пользовательский тип данных находятся в одном блоке, взятом из кучи (об этом рассказывал товарищ, отвечающий в M$ за STL).
Лично я считаю, что крайне глупо стыдиться new (этого слова не стыдятся ни Java, ни C#), а использование make_shared прячет от читающего код довольно важные вещи, не говоря уже о том, что зачастую такая запись получается ощутимо длиннее (сравните m_p(new T()) vs m_p(std::make_shared<T>())).


В заключительной части своего доклада Саттер рассказал о текущем состоянии дел в области книг и компиляторов -- все не так уж и плохо -- сами знаете какую книжку Страуса ждем уже к концу этого года, ну а по компиляторам все должно утрястись буквально в ближайшие пару лет.
Комитет по стандартизации C++ свою работу приостанавливать пока что не намерен, на повестке дня стоит некоторое количество фич, которые не ломают кардинальным образом стиль написания типичного кода (как сломали его вещи типа for-range, auto или lambda), но серьезно упрощают жизнь в некоторых областях (речь идет о фичах типа static if).


Финальный аккорд доклада -- обсуждение вопроса о том, какая сегодня главная проблема в языке C++. Нет, не отсутствие модулей. Не долгое время компиляции и линковки. Не отсутствие рефлекшена. Не однопроходная компиляция...
Главная проблема языка, по мнению Саттера -- очень маленькая стандартная библиотека. Герб специально взял и сравнил ее с библиотеками платформ типа .NET или Java. Речь идет о разнице в несколько порядков.
А как же boost? Герб говорит, что это очень хорошая вещь, но это всего лишь вынужденный ответ на бедность стандартной библиотеки. Кроме того, в boost есть довольно много проблем типа плохо согласованных или дублирующих друг друга вещей, и стандартизация могла бы их решить.
Понятно, что речь идет о добавлении библиотек кроссплатформенных и широко используемых, и тут, на самом деле, просто не паханное поле, начиная с сетевых сокетов, и заканчивая компрессией, криптографией или парсингом XML.
Саттер говорит о том, что почти все крупные корпорации типа Nokia, Facebook, Adobe, Google, Apple, Microsoft имеют очень много кода, который мог бы послужить основой для такого рода библиотек, и он хотел бы видеть представителей этих компаний за столом переговоров в заседаниях комитета по стандартизации C++...

A Concept Design for C++
Многие были сильно опечалены, что концепты все-таки не вошли в стандарт... Этот, довольно таки заунывный, доклад (один из его участников, кстати, Страуструп) о том, что после стольких лет обсуждений никто так толком и не знает что такое концепты и в каком виде они все-таки должны попасть в стандарт.
Ключевая проблема концептов -- лаконичность и простота. К примеру, описание одного из вариантов реализации концептов по своему объему занимало столько же, сколько описание одной из ранних версий всего языка C++. Это не нормально. А в свете лекции Александреску про static if, можно сказать, что возможно концепты не нужны в языке в принципе.

Clang: Defending C++ from Murphy's Million Monkeys
Довольно интересный доклад парня из Google о том, что такое clang и ради чего нужно было затевать написание с нуля yet another C++ compiler.
Один из ответов на этот вопрос такой: C++ очень сложный язык, поэтому, с одной стороны, очень важно иметь качественные инструменты, позволяющие эффективно анализировать и рефакторить код, а с другой -- писать такие инструменты крайне нетривиальная задача по той же самой причине.
Clang изначально проектировался таким образом, чтобы быть не только компилятором, но и инструментом, "понимающим" C++ код и дающий возможность использовать эти знания в других программах.
Собственно сам доклад как раз и был сосредоточен на теме "clang как анализатор ошибок в коде", причем не только ошибок компиляции, но и ошибок более высокого порядка.

Variadic Templates are Funadic
Первый доклад Александреску на тему шаблонов с любым числом аргументов.
Не знаю, где-то я читал про этот доклад отзывы типа "очень понравилось, не смотря на то, что я ни хрена не понял", как по мне -- Андрей пожалел свою аудиторию и выдал очень доступный, интересный и полезный материал. А если прибывать к этому еще и харизму этого товарища, да помножить ее на его отменное чувство юмора, то получится один из самых прикольных докладов на конференции.

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


В качестве небольшого практикума был рассмотрен один из вариантов реализации легендарной типобезопасной функции printf(). Андрей сказал о том, что он считает лучшим решением использовать оригинальный printf плюс дописать перед его вызовом функцию проверки типов аргументов, которую, например для релиз сборок, можно было бы отключать.
Мне этот вариант не очень нравится, хотя бы потому, что парсинг строки форматирования фактически приходится писать два раза.
Реализация такой функции основано на вышеописанном принципе "рекурсивного" разбивания списка типов на голову и хвост.

Еще один практикум -- рассмотрение реализации std::tuple.
Сделано все довольно хитро, на основе "рекурсивного" наследования. Что не нравится Андрею в такой реализации -- layout данных в памяти оказывается в обратном порядке, и более того, сам стандарт не делает никаких допущений по этому поводу.
Еще один занятный момент -- из тупла элемент извлекается не через его метод, а через свободную функцию get, которая берет в качестве аргумента шаблона номер элемента, плюс сам тупл в качестве аргумента при вызове. Такое решение есть следствие определенных ограничений в языке.

Static If I Had a Hammer
Еще один доклад Андрея, на этот раз о фиче, которая пока что не попала в стандарт.
Представьте себе #if, который работает честно на уровне языка и может проверять любые условия, доступные на этапе компиляции, типа тех же type_traits -- это и будет static if.
На самом деле, это в какой-то степени syntax sugar, потому что разные ветки кода, которые выбираются в зависимости от тех или иных условий на этапе компиляции, были давно известны и активно использовались тем же Александреску. Правда в нынешних реалиях делается это все конкретно через жо (специализацию шаблонов) и порождает крайне монструозный код даже для самых тривиальных случаев.
Дополнительный бонус такой фичи -- возможность ее использования в определениях шаблонов (по типу enable_if), что в какой-то мере может даже работать некими концептами для бедных.
В языке D (который был отдельный большим поводом для шуток на конференции -- Андрею запрещали упоминать этот язык вслух) static if давно реализован и очень активно и успешно эксплуатируется.

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

Например, прозвучал вопрос -- почему в constexp функциях запрещен даже оператор if? По факту, реализация такой простой на первый взгляд фичи, как constexp, по сложности вполне себе соизмерима с реализацией variadic templates. Нельзя допускать глубокую или бесконечную рекурсию внутри компилятора, нужно уметь выдавать внятные ошибки etc.
Кстати, Саттер сказал, что variadic templates в реализации тот еще геморрой, и какой-то умный парень в Microsoft сначала сказал, что сделает их за пару месяцев. Сейчас прошло восемь и у него есть еще над чем работать.

Еще один вопрос -- можно ли использовать C++ для программирования ядра операционной системы? Неуча и мракобеса Линуса при обсуждении вопроса никто не упоминал, но на него толсто намекали.
О чем тут вообще говорить, когда типичный патч для Linux выглядит примерно так: "p = kzalloc(sizeof(p), GFP_KERNEL)" меняем на "p = kzalloc(sizeof(*p), GFP_KERNEL)"?
Кстати, была такая замечательная RTOS eCos, очень хорошо спроектированная и довольно качественно написанная на C++ (по сравнению с ней код Linux это просто груда навоза). Увы, сегодня она заброшена по причине того, что в embedded области она не выдержала конкуренции сами понимаете с какой системой...

На этом, пожалуй, тема GointNative 2012 закрыта. Еще раз большое спасибо Microsoft за такое шикарное мероприятие!

зы. Сунул нос в одну из первых книжек по C++11 -- Meyers "Overview of The New C++".

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

No comments:

Post a Comment