Статистика покрытия веток в GCC зависит от ветвления на уровне машинного кода, а не только от веток, явных в исходном коде (if / else, switch / case, для, while, ||, &&,?:,…).Компилятору часто приходится вставлять дополнительные ветви для реализации возможностей языка, особенно в C ++:
- статическая инициализация (C и C ++)
- деструкторы
- обработка исключений
- проверки безопасности, такие как связанные проверки (обычно не используются)
Если GCC разрешено выполнять оптимизацию, это может устранить некоторые из этих ветвей.Вот почему использование -O1
иногда может помочь с данными покрытия.С другой стороны, это усложняет gcov приписывание данных покрытия к правильным строкам исходного кода.
Теоретически можно использовать все ветви машинного кода.Если одна из этих ветвей не обнаружена, это указывает на непроверенный переход состояния.С точки зрения компилятора нет большой разницы между оператором if и вызовом функции, которая может генерировать.Но для вас это не эквивалентно: вы, вероятно, заинтересованы только в тестировании явных веток.
В зависимости от ваших требований к качеству, это разумная позиция.Исчерпывающее тестирование всех ветвей машинного кода невозможно без продвинутых методов, таких как внедрение ошибок.Я лично рекомендую не игнорировать вставленные компилятором ветви, потому что это дает ложное чувство безопасности.
Поэтому мы должны признать, что 50% -ое покрытие ветвей бесплатно только из-за хорошего покрытия операторов, но 100% -ное покрытие ветвей недостижимо,В контексте C ++ покрытие ветвей, вероятно, лучше всего использовать при рассмотрении построчного охвата, а не в виде агрегированной статистики.
GCC позволяет компилировать программное обеспечение без обработки исключений, используя -fno-exceptions
флаг.Вместо того, чтобы генерировать исключение, процесс будет прерван напрямую.Но это фактически переключает вас на несовместимый диалект C ++.Такие вещи, как try / catch, больше не будут работать;проверка ошибок в стандартной библиотеке изменений.Поэтому вы не можете скомпилировать свое программное обеспечение без исключений только для целей покрытия кода.
К счастью, GCC отмечает ветви, которые были добавлены для обработки исключений.Начиная с gcovr 4.2 (еще не выпущен), вы можете использовать флаг gcov --exclude-throw-branches
, чтобы игнорировать открытые ветви только для исключений.Это не идеально: оно не только исключает неявные переходы для некоторой панели обработки исключений, но и переходит к явному предложению catch
.Это может скрыть непокрытое непокрытое, которое вы хотите протестировать.
Gcovrs также предлагает опцию --exclude-unreachable-branches
.Это удаляет данные покрытия филиала, если они относятся к строке, которая, кажется, не содержит полезного кода.Опять же, это может исключить важные данные покрытия, например, если покрытие многострочного оператора относится к строке, которая не содержит полезного кода.Однако это часто помогает исключить ветви, вставленные из-за статических переменных.