首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从断言调用时缺少llvm-cov覆盖。

从断言调用时缺少llvm-cov覆盖。
EN

Stack Overflow用户
提问于 2019-02-01 17:13:55
回答 1查看 338关注 0票数 0

我有以下头文件:

power.hpp:

代码语言:javascript
复制
#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:

代码语言:javascript
复制
#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:

代码语言:javascript
复制
#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:

代码语言:javascript
复制
   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

代码语言:javascript
复制
   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。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-02-05 10:21:38

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

您的第一个想法可能是删除inline标识符,但这是行不通的。这是因为您的编译器很可能很聪明地认识到,square()函数可能是内联的,可以继续运行,并且无论如何都会这样做。最终的结果是外部代码不会被调用。

因此,您需要一种绕过square()函数内联的方法。您可以使用函数指针来完成此操作。请参见对main函数的以下修改:

代码语言:javascript
复制
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);
}

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

power.cpp:

代码语言:javascript
复制
    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:

代码语言:javascript
复制
    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()的调用,因为函数指针不是常量表达式。但是,不要担心,如果您试图在这里用函数指针square(2)替换f_ptr(2),编译器就足够聪明了。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54484144

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档