C++ Builder. Есть ли жизнь после смерти? Мнение одного динозавра

В этой статье я опишу собственные впечатления о последних версиях среды разработки RADStudio от Embarcadero и, возможно, постараюсь помочь кому-то в ответе на вопрос: «А оно мне надо?».

Сразу оговорюсь. Все описанное в этой статье является моим личным мнением и любые сравнения и характеристики, являющиеся плюсами или минусами, являются таковыми только для меня и моего способа использования инструментом. Если для Вас какие-то из указанных достоинств или недостатков так же являются таковыми — очень хорошо, но если это не так, то не стоит впадать в берсерк и начинать крестовую войну. Тут никто не воюет.

Введение

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

Чтобы излишне не растягивать текст, я уберу отвлеченный текст под спойлер.

Обо мне

Моя судьба сложилась так, что я всю свою сознательную жизнь занимался именно программированием. Причем именно прикладным, с небольшим уклоном в системное.

Свой трагичный путь по жизни я начал, когда родителям на работе выдали программируемый микро калькулятор МК-61 и лежать бы ему на полке, если бы я случайно не наткнулся на статью в журнале с программой для него. С этих пор я покатился по наклонной: УПК по информатике с 8 го класса,   аналогичная кафедра в институте и трата 100% на сидение перед компьютером в течении многих лет. Вначале казалось что это так, баловство, что это несерьезно, но, как это обычно и бывает, начав с легких веществ в виде Pascal я закономерно скатился на тяжелые ASM и С++. Казалось что еще недавно я сочиняю безобидные утилиты для Robotron 1715, и вот, не успев оглянуться, я уже клепаю резидентов для DOS, графические интерфейсы под VESA и даже уже пробую Win16 под Windows 3.0.  К тому времени, когда появилась Ebony, я был уже полностью конченный, и оставалось только дождаться появления подобного продукта для C++.

Немного истории CPP Builder

Borland выпустил свой CPP Builder 1.0 с заметным отставанием от аналога для Pascal, но его появление было сравнимо со взрывом сверхновой в области разработки. Это был первый в истории RAD, и, на мой взгляд, единственный. Мне кажется, что ничего сравнимого с ним именно с точки зрения Rapid Application Development нет даже сейчас, на момент написания статьи. И не думаю, что уже появится.

Некоторым в жизни повезло, и они закончили сисадминами, хакерами или смогли завязать и ушли в бизнес. Мне так не повезло, и в своем развитии у меня просто не было выбора. К сожалению, за почти 30 лет своего стажа, я стал заложником именно продукта под названием C++ Builder.

Появление VCL стало революционным прорывом и, следующие почти два десятка лет, альтернатив Borland в разработке прикладного ПО просто не существовало. Были изделия от Microsoft, с самой первой своей попытки создать хоть какое-то средство программирования, никакого сравнения с продуктами от Borland не выдерживающие. Кто-нибудь помнит Microsoft Pascal? А Microsoft C (без приставки Visual)?. Даже в 6й своей версии, это отставало от Borland на поколения, предоставляя программисту средства сравнимые с Turbo C. А ранние версии Visual C со средой программирования, которая названия-то такого не заслуживала — «среда разработки», представляя из себя чахлый редактор с функционалом Notepad и вызовом строчника для компиляции и сборки. И даже уже приобретя гордое звание «Visual Studio», средство от Microsoft оставалось нишевым продуктом для отдельных гиков или тех несчастных, которые не имели другой альтернативы. Еще были и жадный Watcom и прекрасный Symantec с гениальными библиотеками, но никто не мог предложить комплексного решения по действительно быстрому созданию приложений для Windows.

Что же мы имеем сейчас?

Сразу оговорюсь, что рассматривать создание приложений для каких-либо платформ кроме Windows я не буду. С++ Builder, как те таджики, которые ходят по дачным товариществам с вопросом: «Хозяйка, работа есть?», что-то сделать за пределами Windows может, но делает это «плохо, долго и дорого». По моему, никто в здравом уме современные продукты от Embarcadero для этого использовать не будет. Если это не так, то я рад был бы узнать те обстоятельства, когда выбор именно этого инструмента для кросс-платформенной разработки оптимален.

Я буду рассуждать только о создании приложений для Windows и только с использованием VCL. Это, на мой взгляд, единственная ниша, где Delphi и Builder могут что-то стоящее внимания среди множества современных конкурентов.

В настоящее время Builder поставляется с двумя принципиально разными компиляторами. Существует «классический» компилятор для win32, который является очень вяло и слабо адаптированным компилятором от Borland, и пучок изделий на основе LLVM.

Различия классического компилятора и LLVM (clang) — кардинальные. Это продукты из разных экосистем и, в отличии от Microsoft, которая оказалась способной сделать из концепции LLVM что-то работоспособное и совместимое, Embarcadero это не удалось. Clang имеет «гнусные» корни и, соответственно, огромное количество различий с классическим компилятором. Они поддерживают разные стандарты С++, у них разные наборы директив препроцессора, ключевых слов (некоторые общие интерпретируются по разному), разные требования к языку, разная интерпретация предупреждений и ошибок.

Вот несколько примеров.

Найдите ошибку в коде:

struct LZHFileHeader {
  DWORD  OriginalFileSize;
  time_t OriginalFileTime_Create;
  time_t OriginalFileTime_Write;
  time_t OriginalFileTime_Access;
  WORD   OriginalFileNameSize;
  char   OriginalFileName[];
};

struct LZHFileHeaderName : public LZHFileHeader {
  char   _name_place[ MAX_PATH_SIZE ];
};

Если Вы считаете, что ее тут нет, то Вы ошибаетесь:

[bcc32c Error] hs_lz.h(42): base class 'LZHFileHeader' has a flexible array member

Корни проблемы в «char OriginalFileName[]» и, к счастью, решается она всего лишь с помощью добавления нолика в »[0]».  Вроде мелочь, но то, что приходится на пустом месте копаться в древнем бинарном упаковщике, немного напрягает.

Вот проблема посложнее, во всяком случае, для меня:

template  class _AccessBASE {
  protected:
   T *Item;

  public:
    _AccessBASE( T *p ) : Item(p) {}

    int LockRead( void ) { return 1; }
};

template  class ReadAccess : public _AccessBASE {
    int lrc;
  public:
    ReadAccess( T *p ) : _AccessBASE(p) {
      lrc = Item ? Item->LockRead() : 0;
    }
};

По мнению clang ошибок две:

[bcc32c Error] File1.cpp(18): use of undeclared identifier 'Item'
[bcc32c Error] File1.cpp(18): use of undeclared identifier 'Item'

Элемент «Item» в наследнике оказывается даже не недоступным, а вообще неизвестным. Решается абсолютно глупо:

lrc = _AccessBASE::Item ? _AccessBASE::Item->LockRead() : 0;

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

Компиляторы эти настолько разные, что собрать ими обоими совместно какой-то более-менее сложный код попросту невозможно. Для иллюстрации напишем супер интеллектуальную консольную программу без использования VCL:

int main(int argc, char* argv[])
{
	return 0;
}

Соберем ее clang, после чего переключаем настройку «Use classic Borland compiler» в проекте, изменяем что-то в тексте и нажимаем make. Получаем:

bcc32 command line for "File1.cpp"
brcc32 command line for "conTmp.vrc"
ilink32 command line
 [ilink32 Error] Error: Unresolved external '___terminatePTR' referenced from D:\BDS21\LIB\WIN32\RELEASE\CW32MT.LIB|xxv
[ilink32 Error] Error: Unresolved external '__stkchk' referenced from D:\BDS21\LIB\WIN32\RELEASE\CW32MT.LIB|except
[ilink32 Error] Error: Unresolved external '___DefHandler' referenced from D:\BDS21\LIB\WIN32\RELEASE\CW32MT.LIB|except
[ilink32 Error] Error: Unresolved external '___unexpectdPTR' referenced from D:\BDS21\LIB\WIN32\RELEASE\CW32MT.LIB|xxv
[ilink32 Error] Error: Unresolved external '_InitTermAndUnexPtrs()' referenced from D:\BDS21\LIB\WIN32\RELEASE\CW32MT.LIB|xxv
[ilink32 Error] Error: Unable to perform link

В зависимости от того, в каком начальном положении была настройка «классики» букет будет разный. Бакграунд, который используют компиляторы при генерации кода совершенно разный и несовместимый. В данном случае все решает полный ребилд проекта, но осадочек остался, так ведь?

Для полноты иллюстрации совместимости, давайте немного усложним задачу, дописав в нашу программу строчку:

__declspec(dllexport) void F( int n, char str ) {}

Вполне банальный код, но результат у компиляторов разный: оба для win32 экспортируют привычное »@F$qipc», но при переключении на win64 мы получим »_Z1Fic». Вы можете возразить, что закладываться на формат манглинга имен неправильно и нельзя. В идеальном мире это, возможно и так, но, во-первых, ровно так и происходит в VCL загрузка пекаджей и даже у меня в коде есть пара мест, где делается именно это и, во-вторых, даже при добавлении логичного «extern «C», мы все равно получим разный результат. Теперь уже «F» и »_F». В одном и том же проекте, лишь поменяв платформу, мы получаем другой calling-conversion. Если кто-то считает, что это мелочь незаслуживающая внимания, то я Вам искренне завидую.

Мелочи типа SEH, поведение которого в зависимости от платформы и даже конфигурации билда будет разное, я упоминаю чисто для галочки. Т.е. если Вы, вдруг, использовали подобие такого условного кода:

   __try{
      ((int *)0)[1] = 10;
   }__except(1){}

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

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

На мой взгляд, переход на компилятор из «вражеского» лагеря объясняется тем, что Embarcadero просто не имеет ресурсов (возможно и желания) для того чтобы создать и поддерживать собственный. Получив в «наследство» от Borland какой-то инструмент они оказались не способны на существенную его модификацию. Я не знаю как обстоят дела в стане Delphi, но в области С++ мы наблюдаем сползание в сторону наименьшего сопротивления: взять что-то чужое готовое и хоть как-нибудь допилить его в общую экосистему лишь бы закрыть позицию в прайсе. В настоящее время старый компилятор существует в виде «наследия», галочки в проекте «use classic compiler» и, скорее всего, в каких-то будущих версиях будет выброшен.

Классика

Но пока классика еще присутствует, давайте посмотрим, что мы в ней имеем.

При ближайшем рассмотрении, к сожалению, оказывается, что практически ничего. Если Вы, как и я, провели последние лет 15 на неведомой планете, на которой ничего страшнее Builder 5.0 не существовало, то в попытках обнаружить кардинальные изменения в современном «классическом» инструментарии Вы не обнаружите практически ничего. Пара новых ключевых слов из стандарта С++ посвежее, которые не нужны, измененный способ вывода справки о ключах командной строки и несколько новых ключей для совместимости с тем, что Вам все равно не пригодится. На этом, собственно, и все. Если Вы, вдруг, рассчитывали обогатить свой код конструкциями из свежих стандартов С++, то Вам не сюда. Вы не ослышались, на главной странице С++ Builder про С++17 Вас нагло обманули. К классике это не имеет ни малейшего отношения точно так же как и раньше. Если Вы рассчитываете на появление какой-то оптимизации кода или вообще на изменение в его генерации, то нет — это не тут. Лучшее на что Вы можете рассчитывать — это на то, что Ваш существующий код соберется без лишних ошибок времени исполнения.

Для примера возьмем нашу гениальную программу описанную выше. Собрав ее классическим компилятором в «статике» мы получаем файл размером в 70 килобайт. Собрав ее clang для win32, мы получаем файл размером в 174 килобайта. Изменив платформу на win64, мы получим уже 470 килобайт. Чисто для смеха, из аналогично пустой программы на паскале получается 43 килобайта. В принципе, это ни о чем особо не говорит, конечно.

С компилятором clang ситуация другая. Это современный компилятор. Он существенно отстает по всем могущим прийти в голову фронтам от аналога, используемого Microsoft, но, в сравнении с «классическим» компилятором, крайне современный. Другой вопрос,
который меня волнует — это «зачем»? Да, Embarcadero справились с задачей внедрения во «вражеский» стан __closure,  биндинга с кодом из Pascal, но я не могу увидеть в этих их усилиях никакого смысла. В теории с использованием clang можно собирать приложения на VCL и, если Вы вообще часто выигрываете в лотерею, они даже соберутся и, возможно, будут работать. Но смысла в этом подвиге не так уж и много, и причин тому несколько:

  • Существующий код, сколько-нибудь завязанный на специфику платформы (оптимизированный с использованием ассемблера вставками или целиком), часто будет проще выкинуть, чем адаптировать. Виной тому, как синтаксические мелочи типа невозможность использования меток в блоках asm, так и обилие тараканов с caling-conversion.

  • Существующий С++ код, завязанный на чужие или даже свои, но от которых не осталось исходников, библиотеки можно будет выкинуть. Один только фиктивный »__fastcall» ставит жирный крест на попытках подобного code-reusing.

  • Использование всей мощи современного С++ в связке с VCL не имеет никакого смысла т.к. VCL написан исключительно на Pascal и места для применения фич из другого языка в этой библиотеке попросту нет.

  • Embarcadero — это Вам не Microsoft и адаптировать чужеродный язык к существовавшим исторически реалиям они оказались не способны. Реализация clang из комплекта напоминает престарелого франкенштейна: он еще не способен корректно работать со всем старым кодом  из Builder, но уже устарел.

  • То, что лично для меня является определяющим: clang чудовищно, непредставимо медленный.

Итого

Использование классического компилятора дает Вам теоретическую возможность использовать новый продукт от Embarcadero со своими проектами с минимальными усилиями, но с большой вероятностью этот компилятор скоро перестанет существовать.

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

RAD

RAD был бы не RAD, если бы все упиралось только в компилятор.

Компилятор, каким бы он ни был, если он вообще способен генерировать работающий код из текста программы, является только частью общей схемы по разработке программ и, если считать потраченное на его исполнение время, наиболее мизерной частью.

Большая часть RAD — это именно среда разработки и отладки.

Что мы получим в новой среде разработки?

На удивление, текущая среда оставляет о себе приятное впечатление. К счастью, ушли времена чудовищного монстра, написанного на Java, жрущего ресурсы, тормозящего и не умеющего ничего кроме понтов. От многих «модных-и-современных» веяний в «средостроении» Embarcadero почему-то отказались и, в результате, мы имеем вполне адекватную, не перегруженную кучей функций и окошек, вполне привычную для любого разработчика на Delphi\Builder среду, с нормальными и привычными средствами управления проектами, встроенной отладкой и кое-какими украшательствами и удобствами, облегчающими жизнь рядового набивателя текста.

Если Вы застали времена, когда в среде не было человеческой палитры с компонентами, менеджер проектов заключался в задании ключей для утилит командной строки, а отладчик представлял из себя убогий gdb, то можете выдохнуть. Ничего этого больше нет. Все средства вернули в «прошлое», как они и были. Все функционирует очень слитно и ощущается вполне «нативным».

Разумеется, т.к. вся среда разработки теперь снова написана на Pascal и разработчики лишены возможности делать «import github/*», то в прошлое так же ушли практически все современные средства облегчения модификации, контроля и навигации по текстам программ. Если Вы вообще не способны обходиться без разлапистого рефакторинга, code-completion, classes-tree и прочих инструментов, то… Вам наверное стоит вернуться обратно в IDEA. Тут Вам будет очень грустно.

Многие, ставшие стандартными для любой среды разработки, инструменты тут есть и работают, многие просто есть, а многих нет. К примеру, code-completion для С++, в сравнении со старыми версиями теперь просто работает (во всяком случае для «классики»), но работает он с такими условностями и ограничениями, что на практике можно считать, что его вообще нет. В 70% случаев, когда я пытался его использовать, он либо вообще не имеет вариантов, либо предлагает всякий бред, типа каких-то глобальный констант. Пользоваться им можно, но пользы в этом не много просто из-за обилия «холостых» выстрелов в моем случае. Если любить обширную писанину, то, возможно, он будет кому-то полезен.

Refactor же я вообще не смог заставить работать, хотя штука, часто, очень удобная.

В общем, на текущий момент среда разработки представляет из себя стабильную программу, которая работает адекватно быстро, не сыпется под собственным весом и не тормозит. Она позволяет выполнять все необходимые для работы операции.

Лично у меня была единственная проблема связанная именно со средой: к проекту приложения невозможно приписать использование пекаджа. Вообще. Нет такой настройки. Можно указать только общий список пекаджей проекта, но указать, линковать пекадж в виде статической библиотеки или динамической — невозможно. Пришлось править файл проекта руками, благо формат не заумный.

Функционал редактора находится на уровне Notepad++ древних версий, но лично для меня этот критерий находится в самом конце списка важного. Так же нужно учитывать, что средств, предоставляющих тот же code-completion уровня java для С++ в природе не существует и, даже лучшие из них работают весьма условно.

Если кто-то знает инструмент, корректно работающий на основании кода типа такого:

double TWGAViewForm::GetGasData( TxDBGridNode *node, GasTypes tp, GasDataTypes dt )
  {
     switch( tp ) {
#define D( nm ) \
       case gt##nm:  switch( dt ) { \
                      case gdState: return node->IntValues[ gridSTATUS##nm->Index ];\
                      case gdAlarm: return node->IntValues[ gridALARM##nm->Index ];\
                      case gdValue: return node->DoubleValues[ grid##nm->Index ];\
                      case gdError: return node->IntValues[ gridSTATUSERR##nm->Index ];\
                    } break;
       D( CH4 )
       D( CO )
       D( O2 )
       D( H2S )
       D( CO2 )
       D( TEMP )
       D( PRESS )
#undef D
     }

 return 0.0;
}

то я бы очень хотел узнать, что это за средство.

Из плюсов стоит отметить наличие локальной документации. Большая часть ее, к сожалению, уже создается в формате:

void SetXX( int value );

Функция устанавливает ХХ в значение value.

(пол страницы копирайтов и ссылок в никуда) 
…

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

Средства для работы с «классическим» инструментарием.

Они абсолютно привычны, находятся в тех же местах, делают то же самое и точно так же, как это было во всех Builder-ах и 10 и 20 лет назад. К примеру, окно Code view осталось точно таким же тупым и убогим, каким оно было, кажется, с версии 1.0.

47bf4f8a5fd53bf027ba4b48f1d89e66.jpg

В сравнении с ним, окно в 64й версии выглядит чуть умнее:

24a7fc8fc90fb4b2bef8de02e8bca3ed.jpg

Тут уже хотя бы некоторые символы подписывают. Но принципиальной разницы нет. Остальные окошки изменились с древних времен минимально.

807af9a471722a1dfbc1b562ed17020d.jpg

Вообще, ничего, что работало бы хуже, чем раньше я не увидел. Все изменения, которые есть, оставили все инструменты либо на том же уровне, либо сделали их более удобными. Исключение — это разве что дизайнер форм, в котором мне крайне неудобно пользоваться одним окном вместо трех (как это есть в Builder 5) из-за невозможности однозначно перемещаться между ними с клавиатуры, но этот вид внедрен уже очень давно, и считать это недостатком текущей оболочки неправильно.

Многие современные среды могут похвастаться более удобными и интеллектуальными инструментами для отладки и управления. Но для меня лично, в Builder нет ничего, чего мне бы не хватало для комфортной и эффективной работы.

Особенность clang

Самое важное при эксплуатации clang  — это компиляция и линковка. Компилятор чудовищно медленный. Неработоспособность precompiled headers во всей «гнусной» линейке инструментов добавляет к этому еще одну бочку дегтя. Возможность параллельной компиляции по ощущениям проблему не только не решает, с ней становится только хуже. Во всяком случае, у меня получалось почему-то именно так. В общем, я абсолютно не могу представить, как должен быть мотивирован разработчик, чтобы использовать clang в C++ Builder.

Чуть практики

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

За свою жизнь я писал на куче разных компиляторов и под кучу разных платформ, поэтому у меня есть несколько кусков, которые способны собираться вообще чем угодно. Они собирались в разное время такими эксклюзивами как Symantec, Watcom или DMC. Поэтому я решил, что адаптировать их еще под пару компиляторов будет довольно простым занятием.

Полный переход на современный VCL, для меня, к сожалению, невозможен, поэтому собрать какой-то сложный VCL проект я не могу. Я экспериментировал на одной из своих базовых библиотек, которая, чисто для информации, состоит из 151 файла, суммарным объемом около 1.1Мб. Обычно везде пишут количество строк, но я понятия не имею, как его посчитать, да и этот параметр вообще крайне странный на мой взгляд. Объема, думаю, будет достаточно, чтобы получить представление о масштабе теста.

Несмотря на то, что «на берегу» задача адаптировать существующий код под 3 компилятора (win32 classic, win32 и win64 clang) казалась не очень сложной, на ее решение я потратил несколько дней. Процентов 10 времени ушло на допиливание компиляторо-зависимых кусков, процентов 30 на адаптацию кода под 64 бита и все остальное время на войну с clang. Последнее удалось частично т.к. хоть я и смог добиться того, чтобы оптимизированные под х86 куски кода вообще собирались, но тесты под них рассыпались, поэтому я на этот функционал попросту плюнул т.к. слишком много времени уходило на бесцельное ожидание.

К слову, возможно кому-нибудь пригодится табличка версий компилятора (значение константы »__BORLANDC__»).

__BORLANDC__

#define __BC31__         0x0410
#define __BC402__        0x0452
#define __BC450__        0x0460
#define __BC500__        0x0500

#define __BCB10__        0x0520
#define __BCB30__        0x0530
#define __BCB40__        0x0540
#define __BCB50__        0x0550
#define __BCB60__        0x0560
#define __BCB2006__      0x0570 // Developer Studio 2006.
#define __BCB2007__      0x0590 // C++Builder 2007.
#define __BCB2007x__     0x0591 // update 1 to C++Builder 2007.
#define __BCB_RAD2007__  0x0592 // RAD Studio 2007.
#define __BCB_RAD2007x__ 0x0593 // the December update to RAD Studio 2007.
#define __BCB_RAD2009__  0x0610 // C++Builder 2009 and for C++Builder 2009 Update 1.
#define __BCB_RAD2010__  0x0620 // C++Builder 2010 and for C++Builder 2010 Update 1.
#define __BCB_RAD2010x__ 0x0621 // C++Builder 2010 Update 2.
#define __BCB_RADXE__    0x0630 // C++Builder XE.
#define __BCB_RADXEx__   0x0631 // C++Builder XE Update 1.
#define __BCB_RADXE2__   0x0640 // C++Builder XE2.
#define __BCB_RADXE3__   0x0650 // C++Builder XE3 and C++Builder XE3 Update 1.
#define __BCB_RADXE2x__  0x0651 // January 2013 update (BCC32); BCC64 remained at 0x0650.
#define __BCB_RADXE4__   0x0660 // C++Builder XE4 (BCC32 and BCCOSX); BCC64 remained at 0x0650.
#define __BCB_RADXE5__   0x0670 // C++Builder XE5 (BCC32, BCC64, BCCOSX, and BCCIOSARM).
#define __BCB_RADXE6__   0x0680 // C++Builder XE6 (BCC32, BCC64, BCCOSX, BCCIOSARM, and BCCAARM).
#define __BCB_RADXE7__   0x0690 // C++Builder XE7 (BCC32, BCC64, BCCOSX, BCCIOSARM, and BCCAARM).
#define __BCB_RADXE8__   0x0700 // C++Builder XE8 (BCC32, BCC64, BCCOSX, BCCIOSARM, BCCIOSARM64, and BCCAARM).
#define __BCB_RAD90__    0x0710 // C++Builder Seattle (BCC32C, BCC32, BCC64, BCCOSX, BCCIOSARM, BCCIOSARM64, and BCCAARM).
#define __BCB_RAD90x__   0x0711 // C++Builder Seattle Subscription Update 1 (BCC32); other compilers remained at 0x0710.
#define __BCB_RAD100__   0x0720 // C++Builder Berlin (BCC32C, BCC32, BCC64, BCCOSX, BCCIOSARM, BCCIOSARM64, and BCCAARM).
#define __BCB_RAD101__   0x0730 // C++Builder Tokyo (BCC32C, BCC32, BCC64, BCCOSX, BCCIOSARM, BCCIOSARM64, and BCCAARM).
#define __BCB_RAD102__   0x0740 // C++Builder Rio (BCC32C, BCC32, BCC64, BCCOSX, BCCIOSARM, BCCIOSARM64, BCCAARM, and BCC32X).
#define __BCB_RAD104__   0x0750 // C++Builder 10.4 Sydney (BCC32C, BCC32, BCC64, BCCOSX, BCCIOSARM, BCCIOSARM64, BCCAARM, and BCC32X).

Сборка проекта классическиv компилятором, занимает всего в 2–3 раза больше времени чем в С++ Builder 5.0 (при сравнении нужно учитывать, что современное средство компилирует одни и те же тексты дважды).

bcc32 command line for "..\FastMM\FastMM_Client.cpp"
Success
Elapsed time: 00:00:12.8

Сборка проекта силангом… Вот попробуйте догадаться не открывая спойлер, сколько  требуется силангу на сборку того же набора исходных текстов, и сравните свою догадку с реальностью.

Clang

[bcc32c Warning] hdl_loc.h(21): Forced PKG packaging used
Success
Elapsed time: 00:12:06.1 

Удивительно, не правда ли? Во всяком случае я сильно удивился.

Размер кода и оптимизацию я не сравнивал вообще т.к. оптимизация от Borland всегда была посмешищем, а в используемом мной Builder 5.0 сборка в release вообще не работоспособна при многих обстоятельствах и ее нельзя использовать. Как ситуация обстоит в современной версии компилятора глянул только краем глаза. Ситуация прежняя, т.е. никакая. Ну и бог с ней.

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

Несмотря на оптимизацию (установлена в минимальный размер) результат получился довольно странным:

Classic debug
stds_bds_p.bpl – 428Кб
stds_bds_p.lib – 13628Кб

Classic release
stds_bds_p.bpl – 644Кб
stds_bds_p.lib – 2800Кб

Clang win32 release
stds_bds_p.bpl – 433Кб
stds_bds_p.lib – 970Кб

Clang win32 debug
stds_bds_p.bpl – 695Кб
stds_bds_p.lib – 10753Кб

Разбираться в причинах при таком объеме затруднительно, поэтому я и не стал.

Если это читает кто-нибудь их тех, кто преимущественно работает на продуктах наследниках Borland, то он может не до конца оценить всю глубину страданий, которая постигнет любого, пытающегося использовать инструменты с «гнусными» корнями. В них нет не только precompiled headers, но даже file dependency по человечески не работает. Это приводит к тому, что при отладке с мелкими правками при использовании clang накладные расходы на ожидание сборки становятся просто огромными. Т.е. после любой правки текста, от завершения редактирования до запуска нужно каждый раз ждать минуты.

Если Вам кажется, что Delphi собирает проект быстрее чем Builder в разы, то это ничто, между различием «классикой» и clang. Лично у меня нет столько свободного времени в жизни.

Заключение

В заключение, исходя из полученного опыта, я могу дать следующую оценку современному продукту с именем Embarcadero C++ Builder.

О любых применениях clang в этой среде я рекомендую забыть. При работе с VCL он совершенно не нужен, а в тех задачах, где его применение стоит усилий, гораздо оправданнее выбрать другое средство. Его реализация в Builder ущербна, тормозна, громоздка и неудобна. Если на свете вообще существуют какие-то причины применять его в рамках этого продукта, то я с интересом бы о них узнал. Мне в голову не приходит ни одной.

Если Вы разрабатываете приложения на какой-то из версий С++ Builder и, в отличии от меня, в своей работе уже проскочили момент, когда VCL созрел для UNICODE, то я вполне могу рекомендовать Вам рассмотреть современный Builder как цель миграции своих проектов. В VCL появилось очень много нового и часть из этого может оказаться действительно полезным. Некоторые баги библиотеки и средств разработки поправили, средой вполне успешно можно пользоваться. Если у Вас есть достаточно энтузиазма и свободного времени, то рекомендую попробовать. Возможно, Вы получите от перехода на новое средство какую-то выгоду.

Если Вы случайно споткнулись о книгу «C++ Builder за Х дней», если Вы молодой и горячий или перед Вами просто стоит задача выбора средства для быстрого написания интерфейсно-нагруженных приложений под Windows, то С++ Builder это все еще самый лучший RAD на рынке для выполнения этой задачи. Текущее его состояние вполне позволит Вам создавать качественные приложения за минимальное время с вменяемыми усилиями.

Если Вам нужно писать на современном С++, если Вы горите желанием создавать модные интерфейсы и использовать наисвежайшие библиотеки из развалов гов… эээ, шедевров open-sorce разработок, то крайне рекомендую — не тратьте свое время на Builder. Изучайте что-нибудь более живое, модное и современное. Например, Visual Studio.

ПС

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

© Habrahabr.ru