У меня проблемы с пониманием покрытия веток в с ++. Даже для простой программы охват филиала составляет 50%. Когда я использую повышение, охват филиала составляет менее 20%.
Может ли кто-нибудь объяснить мне, почему это происходит? я использую
-fno-exceptions -g -O0 -fprofile-arcs -ftest-coverage -fPIC -Wall
флаги компилятора и gcovr
для генерации отчета. Я тоже пробовал lcov
с точно таким же результатом
Это просто странность компилятора C ++. И gcovr, и lcov зависят от данных покрытия, которые GCC измеряет в объектном коде, и компилятор, кажется, вставляет туда некоторые операторы ветвления.
Я посмотрел на разборка сгенерированного кода на Godbolt, и компилятор действительно вставляет два jne
инструкции ветки в разделе __static_initialization_and_destruction_0
, Они исчезают при компиляции с -O1
,
Какой уровень оптимизации вы должны выбрать для своих измерений покрытия, немного сложно. Чем больше оптимизаций вы включаете, тем сложнее связать измерение покрытия с конкретной строкой исходного кода, потому что компилятор может оптимизировать много кода. Но с C ++ ожидаются некоторые оптимизации, и это сбивает с толку, когда компилятор создает ненужный код. Как и здесь. Какой бы уровень вы ни выбрали, вы не сможете достичь полного охвата филиала.
Документация gcov также обсуждает использование gcov с оптимизацией GCC. Gcov используется gcovr для обработки необработанных данных покрытия, и поэтому имеет те же ограничения.
Тем не менее, gcovr выполняет некоторую постобработку, где он может исключать ветви в строках, которые не содержат исходный код. Здесь это будет игнорировать любые ветви на }
линия, когда дано --exclude-unreachable-branches
флаг.
Других решений пока нет …