我有以下头文件:
power.hpp:
#pragma once
#include <type_traits>
template <typename T, typename R = decltype(std::declval<T>() * std::declval<T>())>
constexpr inline R square(const T& x_) noexcept;power.inl:
#pragma once
#include "power.hpp"
template <typename T, typename R>
constexpr inline R square(const T& x_) noexcept
{
return (x_ * x_);
}power_unit_test.cpp:
#include <power.inl>
int main()
{
static_assert(square(2) == 4);
assert(square(2) == 4);
square(2);
return (0);
}在使用-fprofile-instr-generate和-fcoverage-mapping在使用clang++进行编译之后。运行单元测试二进制时,我得到一个报告,其中告诉我调用了main中的三行中的每一行,但是函数内容只使用了一次。这种使用是从对square(2)的独立调用开始的,断言似乎没有正确地生成覆盖报告。
如果我删除独立的square(2),那么覆盖率不会达到100%,因为断言由于某种原因而无法生成覆盖范围。
报道报告内容如下:
power.inl:
22| | template <typename T, typename R>
23| | constexpr inline R square(const T& x_) noexcept
24| 0| {
25| 0| return (x_ * x_);
26| 0| }power_unit_test.cpp
29| |int main()
30| 1|{
31| 1| static_assert(arc::math::sq(2) == 4);
32| 1| assert(arc::math::sq(2) == 4);
33| 1| // arc::math::sq(2);
34| 1|
35| 1| return (0);
36| 1|}请你能帮我理解一下为什么没有像我在这里期望的那样报道报道吗?这是llvm cov中的一个bug,还是我不理解覆盖的意图?
在MacOS上使用自制的clang7.0.1编译。在构建系统时使用CMake 3.13.2。
发布于 2019-02-05 10:21:38
您遇到的问题是,您的编译器正在为这两个断言方法内联square()函数。由于代码是内联的,所以它从不调用外部代码。
您的第一个想法可能是删除inline标识符,但这是行不通的。这是因为您的编译器很可能很聪明地认识到,square()函数可能是内联的,可以继续运行,并且无论如何都会这样做。最终的结果是外部代码不会被调用。
因此,您需要一种绕过square()函数内联的方法。您可以使用函数指针来完成此操作。请参见对main函数的以下修改:
int main()
{
int (*f_ptr)(const int&); // Ptr to func that takes 'const int&' and returns 'int'
f_ptr = □
static_assert(square(2) == 4); // Cant use 'f_ptr' here
assert(f_ptr(2) == 4);
f_ptr(2);
return (0);
}在上面的代码中,我们将对square(const int&)的显式调用替换为指向函数f_ptr的指针。因此,编译器不会自动内联断言中的函数,代码将被成功调用两次。结果:
power.cpp:
4| |template <typename T, typename R>
5| |constexpr inline R square(const T& x_) noexcept
6| 2|{
7| 2| return (x_ * x_);
8| 2|}power_unit_test.cpp:
5| |int main()
6| 1|{
7| 1| int (*f_ptr)(const int&);
8| 1| f_ptr = □
9| 1|
10| 1| static_assert(square(2) == 4);
11| 1| assert(f_ptr(2) == 4);
12| 1| f_ptr(2);
13| 1|
14| 1| return (0);
15| 1|}一个快速笔记,。由于static_assert本质上是编译时断言,所以不能用函数指针替换对square()的调用,因为函数指针不是常量表达式。但是,不要担心,如果您试图在这里用函数指针square(2)替换f_ptr(2),编译器就足够聪明了。
https://stackoverflow.com/questions/54484144
复制相似问题