How to suppress inlining of templates with gcov

I'm using GCC 4.9 with GCOV to get code and branch coverage. However, the results for branch coverage are utterly useless for my C++ code. It seems GCC inlines templates despite using all -fno-*-inline flags I know of.

Here is a small example application that illustrates the problem:

#include <string>
#include <iostream>

using namespace std;

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

I compile the program with g++ -O0 -fno-inline -fno-inline-small-functions -fno-default-inline --coverage -fprofile-arcs test.cpp -o test

After running test , gcovr -r . -b gcovr -r . -b prints:

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

There is not a single branch in our main function. For example, line 7 contains string foo; . It seems the constructor of std::basic_string<...> has some if statement in it, but that's not useful information when looking at the coverage of main .

The problem is that all these inlined branches sum up and the branch coverage calculated for my actual unit tests are about 40% as a result. I'm interested in the branch coverage of my code, as opposed to how much branches I hit in the C++ standard library.

Is there any way to completely shut down inlining in the compiler or to tell GCOV to not consider inlined branches? I couldn't find any guide on the GCOV homepage or someplace else regarding that topic.

Any help is much appreciated.


Well, you should always double-check your expectations. Thanks a lot @Useless for pointing me to the gcov output itself. You weren't quite right, though: the branches are not attributed to the test.cpp file. Running gcovr with -k and looking at all the intermediate files shows that gcov correctly produces files such as #usr#include#c++#4.9#bits#basic_string.h.gcov that show coverage for the C++ standard library side of things.

However, the reason for all the branches in test.cpp is not inlining. It's exceptions. Each call into the standard library is a branch because of potential exceptions (eg std::bad_alloc ). Adding -fno-exceptions to the compiler flags gives the following output:

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

Digging deeper into the gcov output via cat foo.cpp.gcov prints:

        -:    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

Sorry for the noise.

链接地址: http://www.djcxy.com/p/93412.html

上一篇: 从Bamboo REST API获取应用程序的构建统计信息

下一篇: 如何使用gcov抑制内联模板