Почему практики разработки на основе стандартов важны — даже когда они не обязательны
Выделенная индустрия верификации и валидации — движимая стандартами вроде IEC 61508, ISO 26262, IEC 62304, MISRA C и CWE — возникла для обеспечения того, чтобы ПО было надежным, безопасным и высокого качества. Даже если ваш продукт не попадает под строгие регуляторные требования этих стандартов, принятие их проверенных лучших практик процессов может драматически снизить баги, сократить time-to-market и сократить затраты на обслуживание.
Типы ошибок и инструменты для их устранения
Дефекты ПО делятся на две широкие категории, каждая из которых требует различных техник смягчения:
- Ошибки кодирования — например, выход за границы массива — могут быть обнаружены рано с помощью статического анализа.
- Ошибки приложения возникают, когда код не соответствует своим спецификациям; они раскрываются только через тестирование, основанное на требованиях.
Ошибки кодирования и код-ревью
Статический анализ — мощная первая линия обороны, особенно когда интегрирован в начале проекта. Он идентифицирует нарушения правил кодирования, которые иначе могли стать трудными для отладки багами позже. Дополняет статический анализ, строгий код-ревью проверяет, что код соответствует выбранному стандарту кодирования, такому как MISRA C:2012.
В теории язык, спроектированный для безопасности — Ada, например — устранил бы многие подводные камни через сильную типизацию и явные конструкции. На практике большинство встроенных команд полагаются на C или C++, которые предлагают гибкость, но также раскрывают разработчиков тонким ловушкам вроде неопределенного, неуточненного и реализационно-зависимого поведения. Ограничивая используемые языковые возможности и запрещая рискованные конструкции (например, goto, malloc, смешивание знаковых и беззнаковых арифметик), стандарт кодирования может поднять планку предотвращения дефектов.
Вот несколько распространенных подводных камней, проиллюстрированных в мире C/C++:
- Реализационно-зависимый сдвиг знакового целого: правый сдвиг заполняет старший бит нулями или единицами?
- Неуточненный порядок оценки аргументов функции, который может изменить результат простой рутины вроде
rollDice(). - Смешивание знаковых и беззнаковых значений, что может вести к тонким переполнениям.
Рисунки 1 и 2 ниже демонстрируют, как один и тот же код может вести себя по-разному в разных компиляторах, подчеркивая важность дисциплинированного подхода к кодированию.

Рисунок 1: Поведение некоторых конструкций C и C++ зависит от используемого компилятора. (Источник: LDRA)

Рисунок 2: Поведение некоторых конструкций C и C++ неуточнено языками. (Источник: LDRA)
Принятие устоявшегося стандарта кодирования, такого как MISRA C:2012, помогает избежать этих подводных камней. Правила стандарта покрывают более 300 конкретных практик кодирования, каждое подкрепленное объяснениями, ссылающимися на неопределенное и неуточненное поведения языка. Большинство руководств «решаемые», означая, что инструмент статического анализа может автоматически обнаружить нарушения; несколько «нерешаемых», где инструмент должен пометить потенциальные проблемы, а разработчики решают, реальны ли они.
В апреле 2016 года MISRA расширила свою сферу действия для адресации security-критического ПО, добавив 14 новых руководств. Директива 4.14, например, явно нацелена на неопределенное поведение, предоставляя дополнительный слой защиты для security-ориентированных проектов. Рисунок 4 показывает, как соображения безопасности MISRA согласуются с более широкой структурой безопасности.

Рисунок 4: MISRA и соображения безопасности. (Источник: LDRA)
Ошибки приложения и тестирование требований
Пока стандарты кодирования охраняют от низкоуровневых багов, баги приложения возникают, когда ПО не соответствует своему намеченному поведению. Обнаружение этих требует надежной базы требований и прослеживаемой связи между требованиями, дизайном и кодом.
Двунаправленная прослеживаемость гарантирует, что каждое требование реализовано и каждая реализация может быть прослежена обратно к требованию. Рисунки 5 и 6 иллюстрируют это двустороннее отображение, раскрывая отсутствующую или избыточную функциональность рано в жизненном цикле.

Рисунок 5: Двунаправленная прослеживаемость, с выбранной функцией. (Источник: LDRA)
нажмите для увеличения
Рисунок 6: Двунаправленная прослеживаемость, с выбранным требованием. (Источник: LDRA)
Как только прослеживаемость на месте, тест-кейсы могут быть получены из низкоуровневых требований. Рисунок 7 показывает типичное низкоуровневое требование, полностью специфицирующее поведение одной функции, и Таблица 1 демонстрирует, как тест-кейсы отображаются на эти требования.

Рисунок 7: Пример низкоуровневого требования. (Источник: LDRA)
Таблица 1: Тест-кейсы, полученные из низкоуровневых требований. (Источник: LDRA)
Исполнение этих тестов с юнит-тестовым фреймворком на хосте и таргете подтверждает, что реализация соответствует требованию. Рисунок 8 показывает регрессионный набор, где все тест-кейсы проходят. После выполнения тестов метрики структурного покрытия проверяют, что вся кодовая база была исполнена; любые пробелы побуждают к дополнительным тестам или рефакторингу кода.

Рисунок 8: Выполнение юнит-тестов. (Источник: LDRA)
Заключение
Сложность ПО растет, и так же растет риск дефектов. Лучшие практики разработки — основанные на современном стандарте кодирования вроде MISRA C:2012, строгих метриках, прослеживаемых требованиях и тестировании на основе требований — предоставляют проверенный путь к высококачественному, надежному и робастному коду. Будь то ваш проект связан формальными регуляциями безопасности или нет, дисциплина и прозрачность, которые приносят эти практики, являются чистой выгодой для любой команды разработки.
Встроенный
- Почему Connext DDS Secure — умный выбор для безопасности Industrial IoT
- Почему ручное программирование роботов устарело: примите ИИ-автоматизацию
- Почему агрокурсанты необходимы: улучшение здоровья семян, безопасности посевов и точности удобрений
- NuttX RTOS: Комплексная, бесплатная, POSIX-совместимая реально-временная ОС
- Главные причины выбрать восстановленное промышленное оборудование
- Защитите свои двигатели: основные преимущества линейных реакторов
- Перспективная карьера в транспортировке оборудования и станков
- Когда использовать молотковидный кран: практическое руководство
- Максимизация эффективности с решениями Remote Expert в Industry 4.0
- Максимизируйте возврат: преимущества комиссионных продаж для вашего б/у оборудования