gcov和switch语句

Mat*_*att 12 c c++ gcc gcov

我正在使用switch语句在一些C代码上运行gcov.我已经编写了测试用例来涵盖通过switch语句的每个可能的路径,但它仍然报告switch语句中的一个分支未被采用,并且在"至少采取一次"的统计数据中报告的分支小于100%.

以下是一些示例代码:

#include "stdio.h"

void foo(int i)
{
    switch(i)
    {
        case 1:printf("a\n");break;
        case 2:printf("b\n");break;
        case 3:printf("c\n");break;
        default: printf("other\n");
    }
}

int main()
{
    int i;
    for(i=0;i<4;++i)
        foo(i);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我用" gcc temp.c -fprofile-arcs -ftest-coverage" 构建,运行" a",然后执行" gcov -b -c temp.c".输出指示交换机上的八个分支,一个(分支6)未被占用.

这些分支是什么?我如何获得100%的覆盖率?

Bro*_*ses 5

噢!bde 的程序集转储显示该版本的 GCC 正在将此 switch 语句编译为二叉树的某种近似值,从集合的中间开始。因此它会检查是否i等于 2,然后检查它是否大于或小于 2,然后对于每一边分别检查它是否等于 1 或 3,如果不等于,则采用默认值。

这意味着它有两种不同的代码路径来获得默认结果——一种用于大于 2 且非 3 的数字,另一种用于小于 2 且非 1 的数字。

i<4如果将循环中的值更改为i<=4,以便测试每一侧的路径,看起来您将获得 100% 的覆盖率。

(是的,这很可能从 GCC 3.x 到 GCC 4.x 发生了变化。我不会说它是“固定的”,因为除了使 gcov 结果令人困惑之外,它并不是“错误的”。只是在具有分支预测的现代处理器上,它可能很慢而且过于复杂。)


Mat*_*att 0

我在 Windows 上使用 mingw(这不是最新的 gcc),看起来这可能会在较新版本的 gcc 中得到解决。