2016-09-21 12 views
7

Я использую GCC 4.9 с GCOV, чтобы получить код и зону покрытия. Однако результаты для охвата филиалов совершенно бесполезны для моего кода на C++. Кажется, что GCC строит шаблоны, несмотря на использование всех -fno-*-inline флагов, которые я знаю.Как подавить вставку шаблонов с помощью gcov

Вот небольшой пример приложения, который иллюстрирует эту проблему:

#include <string> 
#include <iostream> 

using namespace std; 

int main() { 
    string foo; 
    foo = "abc"; 
    cout << foo << endl; 
} 

Я компилировать программу с g++ -O0 -fno-inline -fno-inline-small-functions -fno-default-inline --coverage -fprofile-arcs test.cpp -o test

После запуска test, gcovr -r . -b отпечатки:

------------------------------------------------------------------------------ 
          GCC Code Coverage Report 
Directory: . 
------------------------------------------------------------------------------ 
File         Branches Taken Cover Missing 
------------------------------------------------------------------------------ 
test.cpp          14  7 50% 7,8,9,10 
------------------------------------------------------------------------------ 
TOTAL           14  7 50% 
------------------------------------------------------------------------------ 

Существует не одна ветвь в нашей функции main. Например, строка 7 содержит string foo;. Кажется, у конструктора std::basic_string<...> есть некоторая if-инструкция, но это не полезная информация при просмотре покрытия main.

Проблема заключается в том, что все эти встроенные ветви суммируются, и покрытие ответвления, рассчитанное для моих фактических модульных тестов, составляет около 40%. Меня интересует охват моего кода, в отличие от того, сколько ветвей я попал в стандартную библиотеку C++.

Есть ли способ полностью закрыть вложение в компилятор или сказать GCOV, чтобы не учитывать встроенные ветви? Я не мог найти ни одного руководства на домашней странице GCOV или где-то еще по этой теме.

Любая помощь очень ценится.

+2

И что показывают выходные файлы gcov? Весь код библиотеки std будет отнесен к 'test.cpp' в сводке даже без инкрустации, но подробный вывод должен показать, какие фактические функции имеют ветви. – Useless

ответ

4

Ну, вы всегда должны дважды проверять свои ожидания. Большое спасибо @Useless за то, что указал мне на вывод gcov. Однако вы были не совсем правы: ветки не относятся к файлу test.cpp. Запуск gcovr с -k и просмотр всех промежуточных файлов показывает, что gcov правильно создает файлы, такие как #usr#include#c++#4.9#bits#basic_string.h.gcov, которые показывают покрытие для стандартной библиотеки библиотеки C++.

Однако причина для всех ветвей в test.cpp не является составной. Это исключений. Каждый вызов в стандартную библиотеку является ветвью из-за потенциальных исключений (например, std::bad_alloc). Добавление -fno-exceptions к флагам компилятора дает следующий вывод:

------------------------------------------------------------------------------ 
          GCC Code Coverage Report 
Directory: . 
------------------------------------------------------------------------------ 
File         Branches Taken Cover Missing 
------------------------------------------------------------------------------ 
test.cpp          4  2 50% 10 
------------------------------------------------------------------------------ 
TOTAL           4  2 50% 
------------------------------------------------------------------------------ 

Копаем глубже в gcov выход через cat foo.cpp.gcov принтами:

 -: 0:Source:test.cpp 
     -: 0:Graph:/home/neverlord/gcov/test.gcno 
     -: 0:Data:/home/neverlord/gcov/test.gcda 
     -: 0:Runs:1 
     -: 0:Programs:1 
     -: 1:#include <string> 
     -: 2:#include <iostream> 
     -: 3: 
     -: 4:using namespace std; 
     -: 5: 
function main called 1 returned 100% blocks executed 100% 
     1: 6:int main() { 
     1: 7: string foo; 
call 0 returned 1 
     1: 8: foo = "abc"; 
call 0 returned 1 
     1: 9: cout << foo << endl; 
call 0 returned 1 
call 1 returned 1 
call 2 returned 1 
function _GLOBAL__sub_I_main called 1 returned 100% blocks executed 100% 
function _Z41__static_initialization_and_destruction_0ii called 1 returned 100% blocks executed 100% 
     4: 10:} 
call 0 returned 1 
branch 1 taken 1 (fallthrough) 
branch 2 taken 0 
branch 3 taken 1 (fallthrough) 
branch 4 taken 0 

Извините за шум.