C-комитет удалил 45 случаев undefined behavior из стандарта
Reducing undefined behavior in the C language
Мартин Уэкер на Kernel Recipes рассказал, как C борется с undefined behavior: в черновике C2y уже убрано 45 из примерно 100 опасных мест. Компиляторы получают новые предупреждения, статические анализаторы и санитайзеры, а для полной memory safety потребуется либо дорогая проверка во время выполнения, либо формальная верификация.
Проблема, по словам Уэкера, в том, что стандарт позволяет компилятору делать что угодно в ответ на undefined behavior — вплоть до вызова носовых демонов.
- pizlonator
Круто, что здесь упоминается Fil-C, но это ещё и недооценивает его. TFA также недооценивает CHERI. Fil-C не просто «находит много ошибок временной безопасности». Он закрывает ошибки безопасности памяти (пространственной и временной) для авторов эксплойтов и приписывает строгую семантику всему языку. CHERI идёт на некоторые другие компромиссы, но тоже даёт достаточно строгую семантику, чтобы эксплойты на безопасность памяти не работали. И CHERI, и Fil-C более всеобъемлющи, чем Rust, поскольку они атакуют проблему на уровне ABI (и поэтому вы не получаете проблему, когда защита применяется только к тем частям, которые были переписаны на безопасном подмножестве нового языка). Rust можно было бы назвать лучшим в плане времени компиляции, но это не имеет существенного значения, если вас беспокоит определённость семантики или эксплуатируемость.
- chasil
«Некоторые машины Honeywell, например, имели девятибитные байты.»
OS 2200 имеет 36-битные слова. Это всё ещё поддерживаемая платформа.
https://en.wikipedia.org/wiki/UNIVAC_1100/2200_series
Эта платформа была первой реализацией SMP UNIX:
«Любая конфигурация, поставляемая Sperry, включая многопроцессорные, может работать под управлением системы UNIX.»
https://www.nokia.com/bell-labs/about/dennis-m-ritchie/other...
- vrighter
я вообще-то думал начать шуточный проект, который сделал бы UB действительно UB. не в смысле «на практике знаковое переполнение на большинстве современных CPU обрабатывается одинаково». я имею в виду RNG и систему плагинов для компилятора, чтобы вводить новые B в дополнение к U
- hn_submit
Полагаю, это не туда копает, поскольку, ИМХО, C — это просто «высокоуровневый ассемблер» для системного программирования. Как только вы добавляете runtime-поведение для борьбы с неопределённым поведением (UB), вы взрываете время выполнения. А статический анализ может зайти лишь настолько далеко, не взрывая время компиляции.
C — это «правильный инструмент для правильной задачи», а именно операционные системы и их код, который вызывается тысячи раз в секунду. Вы не можете позволить себе ни единой йоты runtime-проверок в таком коде. Разработчик должен знать, что делает, или ему следует уйти с кухни.
Нам следует отговаривать от использования C в прикладном программировании и подталкивать прикладных разработчиков к безопасным языкам вроде Rust или Go.
И я даже не уверен, решает ли Rust этот случай с точки зрения UB.
- rwmj
Думаю, стоит хотя бы упомянуть https://en.wikipedia.org/wiki/CompCert, хотя это и не свободное ПО (лицензия «исходники доступны»). Именно так компании, у которых есть большие кодовые базы на C в отраслях, критичных для безопасности, верифицируют свой код.
- vbezhenar
Моя главная претензия к UB в C — то, что оно молчаливое.
Я не против, чтобы компилятор делал дикие вещи, ладно, как угодно. Ну, я не то чтобы не против, но могу смириться в этом безумном мире.
Но я хочу громких предупреждений! Вроде WARNING: этот условный оператор был свёрнут в одну ветку, потому что более раннее деление на ноль — это UB. И тогда я могу это заметить и переписать или просто убрать это условие.
Я понимаю, что этот код может быть результатом раскрытия макроса. Это нормально. Макросы должны либо включать какие-то прагмы для временного отключения конкретных диагностик, либо пользователь должен окружать использование макроса этими прагмами, если он не может редактировать макрос. С другими предупреждениями это уже происходит.
Или, может быть, компилятор мог бы быть достаточно умным, чтобы отличать раскрытие макроса от честной ошибки пользователя, не знаю.
Помню, как компилятор C++ просто удалил эпилог функции, где я написал простой бесконечный цикл. Это было так безумно. Так что вместо входа в бесконечный цикл моя программа просто продолжила выполнять функцию, которая случайно оказалась слинкована ниже. Представьте себе отладку такого. Ноль диагностик.
- 1vuio0pswjnm7
1790620504 | Reducing undefined behavior in the C language | https://lwn.net/SubscriberLink/1095811/b9325731ea9b61e0/ | https://news.ycombinator.com/item?id=49882419 | 15 comments
1790673092 | Reducing undefined behavior in the C language | https://lwn.net/SubscriberLink/1095811/efcdbcf080cfa4c6/ | https://news.ycombinator.com/item?id=49890290 | 0 comments
- p1necone
Концепция неопределённого поведения, специфичная для C/C++, всегда казалась мне совершенно безумной, и я до сих пор не читал ничего, что заставило бы её казаться менее безумной.