Безопасная разработка на С++ без нарушения обратной совместимости с легаси кодом

febcee5e4e5027f6059400f6b8b09051.jpg

Проблема безопасной разработки на С++ возникла не вчера, и она достигла таких размеров, что рекомендации использовать более надежные языки программирования, принимаются на самом высоком уровне.

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

К сожалению, и сам С++ не особо стремится стать более «безопасным». Точнее, подобное стремление плохо сочетается с требования к стандарту языка, которые принимаются комитетом по стандартизации С++. Ведь любой стандарт должен обеспечивать обратную совместимость со всем старым легаси кодом, что автоматически сводит на нет любые попытки внедрения какой либо новой лексики на уровне единого стандарта С++.

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

Таким образом, возникают, казалось бы, взаимоисключающие и не разрешимые противоречия:


  • Текущее состояние С++ не может гарантировать безопасную разработку на уровне стандартов языка.
  • Принятие новых стандартов С++ с изменением лексики для безопасной разработки обязательно нарушат обратную совместимость с существующим легаси кодом.
  • Переписывать всю имеющуюся кодовую базу С++ под новую безопасную лексику (если бы такие стандартны были приняты), ничуть не дешевле, чем переписать этот же код на новом модном языке программирования.

Но ключевым моментом в предыдущем абзаце является фраза «казалось бы».


Введение в проблематику

Предположим, что существует методика (концепция, алгоритм или набор библиотек), которые гарантируют безопасную разработку компьютерных программ, например, в части безопасной работы с памятью (не важно на каком языке программирования). Тогда должна существовать её формализация до деталей реализации (к сожалению, например в Rust, приводиться только общее описание концепции с простыми примерами, тогда как полный список всех возможных сценариев и выполнение проверок является черным ящиком внутри компилятора языка).

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

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

И именно этот момент (новые правила лексики) фактически и нарушают обратную совместимость со всем старым легаси кодом С++!


Возможна ли безопасная разработка на С++?

Однако мне кажется, что уже сейчас существующие возможности С++ позволяют разрешить данное противоречие без нарушения обратной совместимости со старым кодом. Для этого всего лишь нужно иметь техническую возможность добавлять в компиляторы дополнительные (пользовательские) проверки, которые и должны реализовывать контроль выполнения правил безопасной разработки еще на этапе компиляции программы.

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

Я не рассматриваю реализацию дополнительного синтаксического анализа за счет сторонних приложений (статических анализаторов, например, на базе Clang-Tidy), так как любое внешнее по отношению к компилятору решение, всегда будет содержать как минимум один существенный недостаток — необходимость синхронно поддерживать и использовать одни и те же режимы компиляции исходных текстов программ, что для С++ может быть очень не тривиальной задачей с его препроцессором.

© Habrahabr.ru