The Problems with C++ and Its Evolutionary Dead End

WILD

Administrator
Staff member
ADMIN
SELLER
SUPREME
MEMBER
Joined
Jan 21, 2025
Messages
219
Reaction score
635
Deposit
0$
Проблемы безопасности памяти и неопределенное поведение (UB) — это не ошибки в C++, а глубоко укоренившиеся в стандарте языка. Такие особенности, как макросы, заголовочные файлы, частичная специализация шаблонов, SFINAE и сложные правила инициализации, делают эволюцию чрезвычайно сложной. Любое существенное изменение рискует нарушить работу огромного количества существующего допустимого кода. В результате комитет должен либо сохранить обратную совместимость (включая опасное неопределенное поведение), либо ввести новые параллельные механизмы, что еще больше увеличивает сложность языка.

Парадокс очевиден: чем более устоявшимся становится C++, тем сложнее его улучшать. Организационная инерция, конфликт интересов между поставщиками компиляторов, авторами библиотек, корпорациями и независимыми экспертами, а также необходимость соблюдения принципов нулевых накладных расходов — всё это способствует тупиковой ситуации. Быстро можно добавлять только те функции, которые практически ни с чем не конфликтуют. Для языка, который претендует на звание основного инструмента системного программирования, это стало его ахиллесовой пятой.

Парадокс современных «убийц C++»​

Это объясняет, почему регулярно появляются новые «убийцы C++». Практически каждый новый язык системного программирования в какой-то момент позиционировался как его преемник: более безопасная модель памяти, улучшенная параллельность, более понятные сообщения об ошибках и более современный опыт разработки. Многие из них успешны в своих нишах и часто превосходят C++ по эргономике и безопасности.

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

C++ — это гораздо больше, чем просто язык. Это целая экосистема: ABI, соглашения о вызове функций, бинарные интерфейсы, системы сборки, компоновщики, отладчики, профилировщики, средства очистки памяти, миллионы строк скриптов сборки, библиотеки, состоящие только из заголовочных файлов, и глубоко укоренившаяся культура программирования. Новый язык со своим собственным компилятором (даже если он основан на LLVM) неизбежно создает новый набор барьеров интеграции — смешивание модулей, связывание с существующими библиотеками, отладка, совместимость с исключениями, искажение имен и кроссплатформенное поведение.

Хотя интерфейс внешних функций (FFI) звучит хорошо в теории, на практике «extern C» слишком ограничен для реального взаимодействия с C++, включая шаблоны, встраивание функций, перегрузки, SFINAE и библиотеки, состоящие только из заголовочных файлов.

Современные «убийцы» C++ забыли важный исторический урок. Первый компилятор C++, cfront, был транспайлером, который преобразовывал C++ («C с классами») в обычный C. Это позволило ему мгновенно использовать все существующие компиляторы, компоновщики и инструменты C. Порог внедрения был значительно снижен.

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

Как должен выглядеть настоящий преемник C++?​

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

Транспайлер обеспечивает наиболее важную функцию в масштабах C++: поэтапное внедрение. Вы можете переносить по одному файлу, компоненту или подсистеме за раз, не переписывая все заново. Система сборки, компоновка, ABI и инструменты остаются неизменными.

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

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

Сам C++ победил не потому, что был лучшим языком, а потому, что легко интегрировался с существующей инфраструктурой C. Следующий крупный преемник, вероятно, пойдет по тому же пути — начав с транспайлера, который в первую очередь будет совместим, и только потом станет более безопасным и удобным.
 
Top Bottom