代码覆盖率(Lcov)错误地显示了100%的覆盖率

时间:2020-07-12 10:37:25

标签: c++ code-coverage lcov

我有以下设置(使用g++ 10和lcov 1.14):

g++ SampleScript.cpp -g -O0 -fprofile-arcs -ftest-coverage -o MyScript
./MyScript

lcov -d . -c -o coverage.info --rc lcov_branch_coverage=1
genhtml coverage.info -o cov_out --legend --branch-coverage

使用

/* SampleScript.cpp */

class Container
{
public:
    Container()
        : m_value(0) { }

    Container(int value)
        : m_value(value) { }

    int& value()
    {
        return m_value;
    }

    const int& value() const
    {
        return m_value;
    }

private:
    int m_value;
};

int main()
{
    const Container c;
    return c.value();
}

但是,即使我的代码跳过了2个函数(1个构造函数和1个value()函数),结果输出也无法正确显示100%的覆盖率。 我缺少任何设置吗?

lcov screenshot

1 个答案:

答案 0 :(得分:0)

因为函数是inline。当在类/结构定义中定义成员函数时,它是一个隐式内联函数。编译器仅在调用内联函数时生成代码。 lcov使用GCC内置的gcov覆盖机制,该机制基于在生成的机器代码中插入计数器。所以:

  • 编译器不会为这些函数生成代码
  • 因此gcov不知道这些功能存在
  • 因此lcov不知道这些功能是否存在

这是所有gcov / lcov / gcovr样式覆盖工具的系统限制。

如果您想确保这些工具能够在发现某个函数时识别出它们,请确保它不是内联的(并具有外部链接),或者确保您的测试包含对该函数的调用(即使从未执行过调用)。或使用不同的覆盖率工具自行解析源代码。

C ++中的inline概念并不涉及内联优化,而是与链接和一键定义规则(ODR)相关。函数/对象的定义必须在使用它们的所有编译单元中可见,并且链接程序可以合并其他冲突的定义(ODR的例外)。另一方面,如果不使用内联函数,编译器通常不会发出代码。当用inline关键字标记时,或在类/结构体中定义函数时,函数可以是内联的:

struct Example {
  void inline_function() { ... }
  void also_inline();
  void not_inline();
};

inline void Example::also_inline() { ... }

void Example::not_inline() { ... }
相关问题