10 правил, которые позволяют NASA писать миллионы строк кода с минимальными ошибками

в 12:37, , рубрики: JPL, Блог компании «Hexlet», космические корабли, наса, обучение, отладка, Программирование, Си, хекслет

image
Маргарет Гамильтон стоит рядом с написанным ей исходным кода бортового компьютера «Аполлона»

Лаборатория реактивного движения (Jet Propulsion Laboratory) — научно-исследовательский центр НАСА, ответственный за большинство беспилотных космических кораблей США. Там пишут много кода, и права на ошибку у них намного меньше, чем у обычных программистов.

В JPL пишут на Си, и на их сайте есть документ "JPL Institutional Coding Standard", описывающий жесткие стандарты кодирования внутри организации. Они напоминают правила программирования для встроенных (embedded) систем и систем реального времени, с ограниченными ресурсами. Но многие из правил эти просто принципы хорошего программирования. Ограничение сложности, максимальное упрощение для последующего чтения кода и отладки, отсутствие побочных эффектов. Мы в Хекслете постоянно говорим об этом в вебинарах и, конечно, в самих курсах. Мы считаем очень важным как можно раньше поднимать эти темы, поэтому про функции и побочные эффекты начинаем говорить в самом первом курсе «Основы программирования», который рассчитан на новичков. Это бесплатный курс, кстати, и в нем есть практика на языке JavaScript.

В документе JPL есть много правил, но пользователь Реддита сделал выжимку десяти главных принципов. Вот перевод этого списка.

  1. Нужно сильно ограничивать ветвления и условия. Не использовать goto, setjmp или longjmp, не использовать прямую или косвенную рекурсию.

  2. У всех циклов должен быть предел. Проверящая программа должна иметь возможность легко доказать, что определенное количество итераций не может быть превышено. Если предел невозможно доказать статистически, то правило считается нарушенным.

  3. Не использовать динамическое распределение памяти после инициализации.

  4. Любая функция должна уместиться на одном стандартном листе бумаги, одно выражение на строку и одна строка на определение. Обычно это означает, что функция не должна быть длиннее 60 строк.

  5. В функции должно быть не более двух ассертов. Ассерты используются для проверки аномальных условий, которые не могут произойти при реальном запуске. Ассерты не должны содержать сайд-эффектов, и по формату должны быть Boolean-тестами. Когда ассерт падает, должно запуститься специальное действие по восстановлению, например, возврат условия падения обратно в вызывающую функцию. Если проверяющая программа доказывает, что ассерт никогда не фейлится или никогда не удовлетворяется, то правило считается нарушенным. (Нельзя обойти это правило с помощью бессмысленных “assert(true)”).

  6. Объекты с данными должны быть задекларированы на самом низком (из возможных) уровне области видимости.

  7. Возвращаемое значение не-void функции должно проверяться вызываемой функцией. Валидность параметров должна проверяться внутри каждой функции.

  8. Препроцессор можно использовать только для включения header-файлов и простых макро-определений. Token pasting, вариативные функции и рекурсивные макро вызовы запрещены. Использование условных директив компиляции нежелательно, но иногда неизбежно. Это означает, что только в редких случаях уместно использовать больше чем одно или два условия в директивах компиляции, даже в больших проектах.

  9. Использование указателей должно быть ограничено. Допустимо не больше одного уровня разыменования. Операторы разыменования не должны быть скрыты в макро определениях или внутри typedef. Указатели не функции запрещены.

  10. Весь код должен компилироваться при всех включенных warning'ах, на самых дотошных настройках компилятора с самого первого дня разработки. Весь код должен компилироваться с такими настройками без единого warning'а. Весь код должен проверяться каждый день (как минимум раз в день, но желательно чаще), с использованием лучшего из доступных на текущий день статического анализатора кода, и должен проходить анализ без единого warning'а.

Автор: Hexlet

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js