Почему "продолжить" считается нарушением C в MISRA C: 2004?
MISRA 14.5 говорит, что оператор continue не должен использоваться. Может ли кто-нибудь объяснить причину?
Спасибо.
Ответы
Ответ 1
Именно из-за древних дебатов о goto
, безусловного разветвления и спагетти-кода, который продолжается уже 40 лет. goto
, continue
, break
и несколько операторов return
считаются более или менее одинаковыми.
Консенсус сообщества мирового программирования примерно кончился чем-то вроде: мы признаем, что вы можете использовать эти функции языка, не написав код спагетти, если знаете, что делаете. Но мы все еще отговариваем их, потому что есть большой шанс, что кто-то, кто не знает, что они делают, собирается использовать функции, если они доступны, а затем создает спагетти. И мы также отговариваем их, потому что они являются излишними функциями: вы, очевидно, можете писать программы, не используя их.
Поскольку MISRA-C нацелен на критические системы, MISRA-C: 2004 имеет подход к запрету как можно большего числа этих безусловных особенностей отрасли. Поэтому goto
, continue
и несколько возвратов были запрещены. break
разрешен только в том случае, если в одном цикле был один разрыв.
Однако в проекте "MISRA-C: 2011", который в настоящее время оценивается, комитет решил разрешить все эти функции еще раз, с ограничением, что goto следует разрешать только вниз и никогда не вверх. Обоснование от комитета говорит, что теперь есть инструменты (например, статические анализаторы), достаточно умные, чтобы выявить плохой поток программ, поэтому ключевые слова могут быть разрешены.
Обсуждения по-прежнему все еще сильны...
Ответ 2
Программирование на C делает заведомо трудным отслеживать несколько ветвей выполнения. Если вы где-то выделяете ресурсы, вы должны выпускать их в другом месте, не локально. Если ваши ветки кода, вы, как правило, должны иметь отдельную логику освобождения для каждой ветки или способ выйти из области.
Оператор continue
добавляет еще один способ выхода из области цикла for
и, таким образом, делает такой цикл сложнее рассуждать и понимать все возможные способы управления потоком через него, что в свою очередь затрудняет выяснение того, что ваш код ведет себя корректно при любых обстоятельствах.
Это только предположение с моей стороны, но я полагаю, что попытка ограничить сложность, исходящую из этого дополнительного поведения ветвления, является движущей причиной правила, которое вы упомянули.
Ответ 3
Как и во всех правилах MISRA, если вы можете это оправдать, вы можете отклоняться от правила (раздел 4.3.2 MISRA-C: 2004)
Точка, лежащая за MISRA (и другими аналогичными рекомендациями), заключается в том, чтобы заманить в ловушку вещи, которые обычно вызывают проблемы... да, continue
можно использовать правильно, но данные свидетельствуют о том, что это была общая причина проблемы.
Таким образом, MISRA создала правило для предотвращения использования (ab), и сообщество, проводящее обзор, одобрило это правило. И мнения сообщества пользователей, как правило, поддерживают правило.
Но я повторяю, если вы действительно хотите использовать его, и вы можете обосновать его в своей иерархии, отклонитесь.