Дмитрий Дагаев писал(а):
PSV100 писал(а):
Если быть объективным, то, всё-таки, дополнительная сложность в modern C++
Я не очень понимаю, критикуете Вы меня
или расширяете горизонт.
Про сложность и дырявость C++ тут говорилось предостаточно, но я акцентировал внимание на уязвимость C++ к атакам на переполнение буфера (4 вида). Современные С++ идут по пути сильного развития stl и некоторого усложнения синтаксиса. Решает ли это проблему защиты от переполнения буфера? Не решает.
- во-первых, не все пользуются этими новомодными нововведениями;
- во-вторых, эти нововведения, также имеют проблемы, о которых не все подозревают...
В С++ нет абсолютной гарантии даже при использовании Intel MPX, поскольку, как минимум, из-за исторического груза совместимости возможны всякие преобразования типов, и указатели могут "возникать" где угодно без возможности иметь метаинформацию о границах.
А исходная ремарка (выше в теме) была об ином. Критики нет, было уточнение о том, что сложность в прочих платформах возникает не только (а, может быть, не столько) из-за контроля границ, времени жизни объектов.
В вики для Cyclone -- "safe dialect of the C language" -- в рамках "language features" фактически указаны основные направления ликвидации "предельной наивности" в С, приводящей к уязвимости разного рода:
https://en.wikipedia.org/wiki/Cyclone_(programming_language)#Language_featuresПрезентация о ключевой технике работы с памятью в Rust -- сегодняшнее продолжение Cyclone:
http://smallcultfollowing.com/babysteps/pubs/2013.07.17-NEU.pdf, где акцент на "регионах" (неявных и явных, заимствованных из экспериментов на ML-платформе) в совокупности с прочими семантическими принципами -- для прикидки возникающей сложности при "глобальной борьбе" за корректность (однако основная критика явных "регионов" обычно в другом контексте, который, фактически, не представлен в презентации (как и во многих других) -- в рамках структур данных, определяя "регионы" для полей данных. Кстати, в презентации отмечен некий "bug 810718: Insertion during iteration can allow a foreign website to take over your computer" -- видимо, баг был в продуктах Mozilla, с деталями не разбирался. И ессно, когда необходимо, любое API м.б. построено с проверками границ). Для сопоставления,
"Null Safety", имеющаяся, напр., в Kotlin -- упрощенная, но недостаточная техника (поддержка типового набора операторов для оценки null-значения и компилятор форсирует необходимость проверок, выявляет лишние соответствующие операции), в Eiffel
"Void Safety" чуть сложнее из-за политик инициализации (самоинициализации) -- в Rust (Cyclone/MLKit) осуществляется безопасность "региона" памяти -- совокупности связанных объектов.
Такова базовая безопасность в общем случае (лишь в рамках возможностей системы типизации).
И вот, если в Обероне, к примеру, ввести хотя бы семантическое разделение указателей: допускающие или нет null-значения, допускающие или нет модификацию целевого объекта -- то и в нём существенно увеличится разнообразие и сложность для типизации.
(к слову, в С++ наблюдается и концептуальная неоднозначность -- разделение "логической" и "физической" константности -- спецификатор "mutable" для полей класса, допускающий модификацию в const-методах -- теперь концепция с натяжкой согласуется с понятием уникальных (линейных) типов. И модификатор "const" весьма условный -- может быть снят при преобразовании типов данных, что в случае реальной модификации объекта приводит к "undefined behaviour", возможен и крах, если, напр., объект расположен в защищённой памяти)