Как известно, скоро выйдет GCC 6. В нем содержится множество улучшений, включая экспериментальную поддержку новых возможностей C++17 (концепты, std::invoke, std::shared_mutex и т.д.) и значительно более "умные" предупреждения, помогающие разработчикам писать безопасный и надежный код. Фактически GCC 6 со всеми включенными предупреждениями делает некоторые статические анализаторы кода неактуальными.
Бессмысленно описывать все новые возможности GCC 6 в этой статье, поэтому я не буду. Те, кому это интересно, могут прочитать об этом на других сайтах, распространяющих информацию о грядущем релизе GCC 6 (к примеру, здесь или здесь). Однако я хотел бы рассказать об использовании GCC 6 для разработки под Android и, в частности, о будущем GCC в составе CrystaX NDK.
Как известно, последний Android NDK от Google (r10e на текущий момент) включает как GCC, так и Clang. Оба при этом несколько устаревшие: GCC версии 4.9 и Clang версии 3.6. В последней половине 2015-го года наблюдалась повышенная активность в публичных репозиториях Google NDK, так что это выглядит так, что Google готовится внести серьезные изменения в Android NDK. В частности, в нем более не будет GCC и единственным поддерживаемым компилятором для разработки под Android останется Clang. Это явно обозначено в CHANGELOG.md:
- GCC в NDK объявлен устаревшим.
- Пора начинать использовать Clang если вы еще этого не сделали. Если у вас проблемы с Clang-ом, пожалуйста сообщайте об ошибках!
- GCC в NDK не будет обновлен до версии 5. Также мы не будем принимать некритические правки.
- Исправление ошибок компилятора GCC 4.9 будет производиться по факту, рассматривая каждый случай в отдельности.
Ну что ж, Google волен делать так (прекратить поддержку GCC). Однако мы не думаем, что это правильно, особенно принимая во внимание как GCC улучшается со временем – поэтому мы определенно не намерены прекращать поддержку GCC в CrystaX NDK. Фактически, существует много областей, в которых GCC есть что сказать, по сравнению с Clang, несмотря на то, что LLVM/Clang очень интересный проект и уже предоставляет очень высокое качество. Жизнь учит нас что для пользователей всегда лучше наличие конкуренции, чем использование чего-то одного. Это в точности случай с конкуренцией между GCC и Clang - оба становятся лучше с течением времени, и мы все только выигрываем от этого.
Имея это в виду, мы включили последний GCC 5.3 в последний релиз CrystaX NDK 10.3.1, позволив нашим пользователям воспользоваться всеми достижениями GCC при разработке под Android; теперь время для включения туда же GCC 6, хоть он пока еще и не выпущен официально. GCC 6 находится в стадии исправлений регрессий и документации, поэтому мы попробовали интегрировать его в CrystaX NDK и сейчас, после прохождения всех наших автоматических тестов, мы счастливы сообщить что GCC 6 практически полностью пригоден и для разработки под Android!
Единственные регрессии на данный момент: #1292 и #1293. Ниже приводится небольшое разъяснение по ним:
Это в чистом виде регрессия в GCC 6 по сравнению с GCC 5. Насколько мы видим, эта регрессия не имеет никакого отношения к Android, поэтому мы ожидаем ее исправления в основном проекте GCC. Похожая ошибка #68730 уже зарегистрирована в публичном баг-трекере GCC, но она уже закрыта, поэтому не полностью ясно, имеет ли отношение наша ошибка #1292 к ошибке GCC #68730, или же это просто совпадение. В любом случае мы работаем над этим и вскоре сообщим в апстрим GCC о ней, так что есть хорошие шансы получить ее исправление к моменту релиза GCC 6.
Это наша регрессия. В GCC 5 этой проблемы не было. Вкратце, суть проблемы в том, что GCC генерирует неэффективный код для доступа к глобальным переменным в позиционно-независимом (position-independent) коде. Эта проблема давно известна, но до сих пор не решена в основной ветке GCC. Мы же ведем собственный форк GCC в CrystaX NDK, пытаясь не отдаляться слишком сильно от основного проекта, но также добавляя важные исправления из GCC от Google. Исправление данной ошибки как раз является таким важным добавлением, поэтому мы портировали его в собственный GCC 5.3, вошедший в состав CrystaX NDK 10.3.1. Однако при попытке портирования этого исправления в GCC 6 мы столкнулись с проблемами, связанными с серьезными внутренними изменениями в коде GCC, делающими перенос данного исправления не столь тривиальной задачей. Будучи перенесенными в код GCC 6 "как есть" (с исправлением очевидных конфликтов), код перестает быть компилируемым из-за серьезных изменений во внутренних структурах GCC и, вообще, внутренней логики оптимизатора.
Кратко говоря, это действительно регрессия, поэтому мы, конечно же, будем ее чинить. Тем не менее, даже в нынешней ситуации она не сильно повлияет на ваши приложени, если только вы не используете глобальные переменные слишком часто (что в любом случае является плохой практикой).
Принимая во внимание вышеизложенное, имеет смысл начать использовать GCC 6 прямо сейчас, не дожидаясь окончательного релиза. Мы уверены, что использование GCC 6 в ваших проектах приведет к улучшению общего качества кода в силу задействования вышеупомянутых алгоритмов умного анализа кода, реализованных в GCC 6. А также не забывайте о C++17 - грядущий стандарт выглядит очень многообещающе для мира C++, добавляя множество очень интересных и важных возможностей, делая тем самым разработку на C++ еще более мощной. Поэтому имеет смысл начать реальное использование этих возможностей прямо сейчас, не дожидаясь, когда будет поздно.
Мы готовимся к выпуску новой версии CrystaX NDK, и GCC 6 будет включен в нее. Тем временем вы можете воспользоваться нашими регулярными билдами с https://dl.crystax.net/builds/. Имейте в виду, что для использования GCC 6 необходим билд №810 или выше. Не забывайте сообщать нам о выявленных проблемах; мы будем счастливы помочь!