https://www.opennet.ru/opennews/art.shtml?num=62821
Бьёрн Страуструп (Bjarne Stroustrup), создатель языка C++, призвал комитет WG21, отвечающий за разработку стандартов для языка C++, предпринять меры для сохранения актуальности C++ в условиях активного продвижения инициатив по переходу на языки, обеспечивающие безопасную работу с памятью. Страуструп считает, что язык С++ уже содержит все возможности, необходимые для безопасной работы с памятью. Остаётся только предоставить средства, гарантирующие, что код написан с использованием только безопасных возможностей.
По мнению Страуструпа, времени осталось очень мало и необходимо до 2026 года успеть предпринять какие-то меры, так как Агентство по кибербезопасности и защите инфраструктуры США и ФБР стали более активно продвигать среди производителей ПО идею перехода на языки, безопасного работающие с памятью. До 2026 года производителям ПО рекомендовано разработать план по применению в своих продуктах технологий, защищающих от ошибок при работе с памятью, или переходу на использование языков, безопасно работающих с памятью.
Стандартизация возможностей для безопасной разработки на C++ позволит сохранить интерес к языку С++, особенно с учётом того, что разработчики существующих проектов на С и C++ смогут постепенно наращивать безопасность своих продуктов, не прибегая к инициативам по переписыванию на другом языке. В частности, проекты на C можно преобразовать в код С++, а за тем поэтапно переводить код на безопасные конструкции, следуя рекомендациям из руководства «C++ Core Guidelines».
Для обеспечения разработки безопасного кода Страуструп предлагает стандартизировать систему профилей C++, вводящих дополнительные требования к коду. Профили близки к применению флагов
-Wall
и-Wextra
при компиляции, но в отличие от них работают на уровне запрета применения определённых возможностей языка. К реализации предлагаются профили для безопасных типов, контроля времени жизни объектов, работы с допустимыми диапазонами значений и целочисленной арифметики. Привязку к профилям можно задавать не только для проекта и файлов (например,[[profile::enforce(type)]]
), но и включать/отключать на уровне отдельных конструкций (например,[profile::suppress(lifetime))] this->succ = this->succ->succ;
).
Работа по повышению безопасности будет сводится к включению профиля для определённого кода и переписыванию частей, использующих небезопасные возможности языка, охватываемые выбранным профилем. Например, использование профилей поможет уйти от применения в коде сырых указателей и массивов, избавиться приведения типов и защититься от обращений к неинициализированным объектам. Вместо сырых указателей можно использовать, например, умные указатели std::unique_ptr и std::shared_ptr с отслеживанием владения. При наличии в коде циклов «for», перебирающих отдельные элементы Си-массива, потребует заменить данные циклы на вариант с обработкой диапазонов
for(type variable : vector)
, использующий std::vector.
Предложены следующие профили:
- type – каждый объект должен быть инициализирован, не допускается приведение типов.
- lifetime – запрещены ссылки на освобождённые или неиспользуемые области памяти, разыменование указателей, явный вызов new/delete.
- bounds – требуется проверка допустимых диапазонов при работе с указателями, запрещены арифметические операции с указателями.
- arithmetic – блокируются целочисленные переполнения, запрещены знаковые/беззнаковые преобразования, изменяющие значение.
- concurrency – исключает операции, приводящие к взаимным блокировкам и состояниям гонки.
- RAII (Resource Acquisition Is Initialization) – требует проверки владения для каждого ресурса.
Гарантии, реализуемые при использовании профилей:
- Обращение к объекту допускается только в соответствии с типом, под которым этот объект был определён.
- Каждый объект должен быть корректно создан и освобождён.Каждый объект должен быть корректно создан и освобождён.
- Каждый указатель должен указывать на корректный объект или нулевой указатель.
- Каждая ссылка через указатель не должна переходить по нулевому указателю.
- Каждое обращение через индексированный указатель должно находиться в пределах допустимого диапазона.