When I run gcovr after running my unit test suite I get wrong number for coverage of header files where some inline member function definitions are placed. For example:
----------------------------------------------------------------------------
File Lines Exec Cover Missing
------------------------------------------------------------------------------
include/analysis/dataobjects/DetailedHit.h 6 2 33% 41-43,45
include/analysis/dataobjects/Hit.h 19 0 0% 31-33,35-36,42-43,50-51,58-59,74-75,82-83,90-91,98-99
For Hit.h
the reported coverage is 0%, but I'm sure that at least some code from that header is executed during the unit test run since if I place a cout in it then I see it in the console ouptut. On the web it is often suggested that it is a problem coming from the fact that the compiler inlines the member function code, so that no function call is generated and thus the coverage tools do not track the execution. So I added the flags:
-fno-inline -fno-inline-small-functions -fno-default-inline
to the invocation of the compiler (gcc 8.2.1) but I get the same coverage report. So I don't understand what's happening.
The thing that mostly puzzles me is why gcovr reports 2 covered lines in DetailedHit.h
. This header is very similar to Hit.h
so I'd expect the same behavior with 0% reported coverage, but this member function:
const std::vector<Herd::ParticleHit> ParticleHits() const {
return _particleHits;
}
results to be executed 10 times. It is a simple function so it should be inlined as the ones in Hit.h
, still it results to be covered. In case it matters, Hit is a concrete base class for DetailedHit, and both do not have virtual methods.
I think I'm missing some important piece of knowledge about how gcov and gcovr work, but I couldn't find a relevant clue on the web so I'd appreciate any help on this. Thanks.
The methods with 0% coverage were inline methods in a header.
I did compile the library I was testing with gcc --coverage
which instruments the machine code to collect coverage. However, I did not instrument the test executable since I am not interested in the coverage of the tests themselves. So the test executable contained code for the inline methods without instrumenting them.
As a result, the methods were known to gcov but no coverage was collected (only the non-instrumented inline version was executed).
The solution:
--coverage
compiler flag-e
/--exclude
gcovr option