gpt4 book ai didi

c++ - 从断言调用时缺少 llvm-cov 覆盖

转载 作者:行者123 更新时间:2023-11-28 04:25:13 24 4
gpt4 key购买 nike

我有以下头文件:

电源.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;

功率输入:

#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);
}

在使用 clang++ 中使用标志 -fprofile-instr-generate-fcoverage-mapping 编译之后。运行单元测试二进制文件,我得到一份报告,告诉我 main 中的三行中的每一行都被调用了,但是函数内容只被使用了一次。此用法来自对 square(2) 的独立调用,断言似乎无法正确生成覆盖率报告。

如果我删除独立的 square(2),则覆盖率不会达到 100%,因为断言由于某种原因未产生覆盖率。

覆盖率报告如下:

功率输入:

   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 中的错误还是我不理解覆盖意图?

在 MacOS 上使用自制程序的 clang 7.0.1 进行编译。使用 CMake 3.13.2 作为构建系统。

最佳答案

您遇到的问题是您的编译器正在为两个断言方法内联 square() 函数。由于代码是内联的,它永远不会调用您的外部代码。

您的第一个想法可能是删除 inline 标识符,但这行不通。这是因为您的编译器很可能足够聪明,可以识别 square() 函数可以被内联并继续执行它。最终结果是外部代码没有被调用。

因此您需要一种方法来绕过 square() 函数的内联。您可以使用函数指针来执行此操作。查看对 main 函数的以下修改:

int main()
{
int (*f_ptr)(const int&); // Ptr to func that takes 'const int&' and returns 'int'
f_ptr = &square;

static_assert(square(2) == 4); // Cant use 'f_ptr' here
assert(f_ptr(2) == 4);
f_ptr(2);

return (0);
}

在上面的代码中,我们用指向函数的指针 f_ptr 替换了对 square(const int&) 的显式调用。因此,编译器不会自动内联断言中的函数,代码将被成功调用两次。结果:

电源.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 = &square;
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() 的调用,因为函数指针不是 constant expressions .但别担心,如果您在此处尝试将 square(2) 替换为函数指针 f_ptr(2),您的编译器会很聪明地发出警告。

关于c++ - 从断言调用时缺少 llvm-cov 覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54484144/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com