Today I was rewriting my matrix class to be constexpr
. I have(had) 100% unit test coverage on this class but I noticed after I converted almost all functions to constexpr a part of the constructor is marked in the lcov as no longer covered at all.
Here is the class with just the constructor.
template<typename T, std::size_t m, std::size_t n>
class Matrix
{
static_assert(std::is_arithmetic<T>::value,
"Matrix can only be declared with a type where "
"std::is_arithmetic is true.");
public:
constexpr Matrix(
std::initializer_list<std::initializer_list<T>> matrix_data)
{
if (matrix_data.size() != m)
{
throw std::invalid_argument("Invalid amount of rows.");
}
for (const auto& col : matrix_data)
{
if (col.size() != n)
{
throw std::invalid_argument("Invalid amount of columns.");
}
}
std::size_t pos_i = 0;
std::size_t pos_j = 0;
for (auto i = matrix_data.begin(); i != matrix_data.end(); ++i)
{
for (auto j = i->begin(); j != i->end(); ++j)
{
this->data[pos_i][pos_j] = *j;
++pos_j;
}
++pos_i;
pos_j = 0;
}
}
private:
std::array<std::array<T, n>, m> data{};
};
int main()
{
Matrix<double, 2, 2> mat = {
{1, 2},
{3, 4}
};
return 0;
}
I am using gcc 7.2 with lcov 1.13
I have(had) 100% unit test coverage on this class but I noticed after I converted almost all functions to
constexpr
a part of the constructor is marked in the lcov as no longer covered at all.
lcov
's indication of non covered code means that gcov
didn't instrument it.
Anything marked constexpr
is evaluated at compile time, gcov
coverage data is gathered at runtime.
So that's one reason I'd suspect, why you don't get coverage data for any constexpr
function.
As you have templated code, I'm not sure if I'm up to date, but I experienced that gcov
doesn't instrument templates very well, and you might be left with zero coverage data for them.
Similar reasoning as with what I said above for constexpr
, templates are evaluated/instantiated at compile time. It would be at least hard to instrument all actually used template instantiations in a reasonable way.