c++ - 如何解释模板函数调用的 gcov 结果

标签 c++ templates code-coverage gcov

问题 1:如何破译函数名称,例如 _ZN21CircularBufferManager4readIlEEmPT_m ?我猜那些长函数名(即 l、t、h、d)中“read”之后的第二个字符一定与类型有关。我使用 unsigned char、unsigned short、signed long、double。

问题 2:在第 227 行中,我看到 16 个分支。为什么是 16?另一方面,第 222 行有 8 个分支,这对我来说很有意义,因为 2 个状态(真或假)乘以 4 个函数得到 8 个分支。

        -:  216:    template<typename Type>
function _ZN21CircularBufferManager4readIlEEmPT_m called 2 returned 100% blocks executed 63%
function _ZN21CircularBufferManager4readItEEmPT_m called 2 returned 100% blocks executed 50%
function _ZN21CircularBufferManager4readIhEEmPT_m called 10 returned 100% blocks executed 94%
function _ZN21CircularBufferManager4readIdEEmPT_m called 8 returned 100% blocks executed 94%
       22:  217:    uint32 read(Type* data, uint32 element_count)
        -:  218:    {
       22:  219:        uint32 size(sizeof(Type)*element_count);
        -:  220:
       22:  221:        uint32 write_pos_alias(this->write_pos);
       22:  222:        if (this->read_pos > this->write_pos) {
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
branch  2 taken 0% (fallthrough)
branch  3 taken 100%
branch  4 taken 20% (fallthrough)
branch  5 taken 80%
branch  6 taken 13% (fallthrough)
branch  7 taken 88%
        3:  223:            write_pos_alias += this->allocated_size;
        -:  224:        }
        -:  225:        assert(write_pos_alias >= this->read_pos);
       22:  226:        uint32 n(write_pos_alias - this->read_pos); // number of bytes to reach the write position
       22:  227:        if (n==0 && this->stored_count==0) // <=> buffer is empty
branch  0 taken 50% (fallthrough)
branch  1 taken 50%
branch  2 taken 100% (fallthrough)
branch  3 taken 0%
branch  4 taken 0% (fallthrough)
branch  5 taken 100%
branch  6 never executed
branch  7 never executed
branch  8 taken 30% (fallthrough)
branch  9 taken 70%
branch 10 taken 0% (fallthrough)
branch 11 taken 100%
branch 12 taken 38% (fallthrough)
branch 13 taken 63%
branch 14 taken 0% (fallthrough)
branch 15 taken 100%
        -:  228:        {
        -:  229:            // no data read
        1:  230:            return 0;
        -:  231:        }
       21:  232:        else if (0<n && n<size) // read is stopped before read_pos crosses over write_pos.
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
branch  2 taken 0% (fallthrough)
branch  3 taken 100%
branch  4 taken 100% (fallthrough)
branch  5 taken 0%
branch  6 taken 0% (fallthrough)
branch  7 taken 100%
branch  8 taken 70% (fallthrough)
branch  9 taken 30%
branch 10 taken 14% (fallthrough)
branch 11 taken 86%
branch 12 taken 63% (fallthrough)
branch 13 taken 38%
branch 14 taken 20% (fallthrough)
branch 15 taken 80%
        -:  233:        {
        2:  234:            return read(reinterpret_cast<uint8*>(data), n); //less data than required.
call    0 never executed
call    1 never executed
call    2 returned 100%
call    3 returned 100%
        -:  235:        }
        -:  236:        // It is guaranteed here and below that read_pos never crosses-over write_pos.
        -:  237:
       19:  238:        if (this->read_pos + size > this->allocated_size) // going beyond the end of buffer
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
branch  2 taken 0% (fallthrough)
branch  3 taken 100%
branch  4 taken 11% (fallthrough)
branch  5 taken 89%
branch  6 taken 43% (fallthrough)
branch  7 taken 57%
        -:  239:        {
        4:  240:            uint32 n(this->allocated_size - this->read_pos); // number of bytes to reach the end of buffer
        -:  241:            return this->read(reinterpret_cast<uint8*>(data), n)
        4:  242:                 + this->read(reinterpret_cast<uint8*>(data)+n, size-n);
call    0 never executed
call    1 never executed
call    2 never executed
call    3 never executed
call    4 returned 100%
call    5 returned 100%
call    6 returned 100%
call    7 returned 100%
        -:  243:        }
       15:  244:        memcpy(reinterpret_cast<void*>(data), reinterpret_cast<void*>(this->buf+this->read_pos), size);
       15:  245:        incrementReadPos(size);
call    0 returned 100%
call    1 returned 100%
call    2 returned 100%
call    3 returned 100%
       15:  246:        return size;
        -:  247:    }

最佳答案

对于您的第一个问题,您可以通过 c++filt 命令通过管道传输此输出以分解标识符。

对于你的第二个问题,显然 gcov 并不关心 false 是否短路,它仍然计算三种方法来得到 false,只有一种方法可以得到 true。

  • true => n==0 && this->stored_count==0
  • false => n!=0 && this->stored_count==0
  • false => n!=0 && this->stored_count!=0
  • false => n==0 && this->stored_count!=0

由于您以 4 种方式扩展模板函数,因此共有 16 种。

关于c++ - 如何解释模板函数调用的 gcov 结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19194316/

相关文章:

c++ - 我可以设置 array[n+k] = array[0] 吗?

C++ 将 2 个字符串合并在一起

c++ - 指定可选模板参数的子集

java - 为什么 Cobertura 在通过 Eclipse 插件运行时报告覆盖率为 0%?

c++ - 如何使用 vector c++迭代文件中单词的位置

c++ - 使用 ifstream getline 意外退出循环

C++ 将 std::function 对象传递给可变参数模板

c++ - 使用模板读取 vector

javascript - 我怎样才能用 cucumber 覆盖 Protractor

python - coverage.py 针对 .pyc 文件