Пункт 1. который вы хотите сделать, является стилистическим вопросом. Программа имеет смысл, даже если условия не являются эксклюзивными. Лично, как автор инструментов статического анализа, я думаю, что пользователи получают достаточно ложных сигналов тревоги, не пытаясь навязать им стиль (и поскольку другой программист специально напишет условия перекрытия, для другого программиста то, что вы спросите, будет ложной тревогой) , Тем не менее, существуют инструменты, которые можно настраивать: для одного из них вы можете написать правило, гласящее, что случаи должны быть исключительными, когда встречается эта конструкция. И, как предлагает Джеффри, вы можете обернуть свой код в контекст, в котором вы вычисляете логическое условие, которое истинно, если нет перекрытия, и вместо этого проверить это условие.
Пункт 2. не является проблемой стиля: вы хотите знать, может ли возникать исключение.
Проблема сложна в теории и на практике, поэтому инструменты обычно отказываются, по крайней мере, от одной из правильности (никогда не ошибаются, если есть проблема) или полноты (никогда предупредить за неисполнение). Если бы типы переменных были неограниченными целыми числами, теория вычислимости утверждала бы, что анализатор не может быть и правильным, и полным, и завершаться для всех входных программ. Но хватит теории. Некоторые инструменты теряют правильность и полноту, но это не значит, что они также бесполезны.
Примером правильного инструмента является Анализ значений Frama-C : если он говорит, что утверждение (например, последний случай в последовательности elseif) недоступно, вы знаете, что оно недоступен Он не завершен, поэтому, когда в нем не говорится, что последнее утверждение недоступно, вы не знаете.
Примером готового инструмента является Cute : в нем используется так называемый concolic подход для автоматической генерации тестовых случаев с целью структурного охвата (то есть он будет более или менее эвристически пытаться генерировать тесты, которые активируют последний случай, как только все остальные были взяты). Поскольку он генерирует тестовые случаи (каждый из которых представляет собой определенный входной вектор, на котором фактически выполняется код), он никогда не предупреждает об отсутствии проблем. Вот что значит быть завершенным. Но он может не найти тестовый пример, который приводит к тому, что последнее утверждение будет достигнуто, даже если оно есть: оно неверно.