Reputation: 21604
Consider this simple piece of code:
#include <iostream>
#include <sstream>
class Utl
{
public:
// singleton accessor
static Utl& GetInstance();
virtual std::string GetHello( bool full ) = 0;
};
class UtlImpl : public Utl
{
public:
UtlImpl() {}
virtual std::string GetHello( bool full )
{
return (full)?"full":"partial";
}
};
Utl& Utl::GetInstance()
{
static UtlImpl instance;
return instance;
}
int main( int argc, char* argv[] )
{
std::cout << Utl::GetInstance().GetHello(true) << std::endl;
std::cout << Utl::GetInstance().GetHello(false) << std::endl;
return 0;
}
I compile this with Visual Studio 2015 in "Debug" and "RelWithDebInfo" mode.
Then I use a coverage validation tool (Software verify - Coverage Validator).
For the Debug build, the tool reports a 100% coverage
For the RelWithDebInfo build, the tool reports a 66.67% coverage. It reports the function Utl::GetInstance()
has not been executed.
As RelWithDebInfo is optimized, I suspect that's because the function has been inlined by the compiler (I'm not familiar with assembly code to verify that, but I can post anything that would help if someone explains me how to check this). But when I use Software verify's DbgHelp browser tool, this one reports that a Utl::GetInstance()
is present in the binary.
Is it possible that Visual Studio inlined the code of Utl::GetInstance()
function but also kept a "real" Utl::GetInstance()
in the binary (then possibly ending with two implementations of this code)? That would explain why the tool reports me the function has never been called, while its code has definitely been executed...
Upvotes: 0
Views: 105
Reputation: 13187
Any function that has global scope needs to have a callable function as well as the inlined function, so there will be duplicates.
Setting "Inline function expansion" to "Disabled (/Ob0)" when building allows OP to get 100% coverage for test.
Upvotes: 1