10 правил, які дозволяють NASA писати мільйони рядків коду з мінімальними помилками

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'а.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.