【发布时间】:2014-01-18 22:12:30
【问题描述】:
这个函数末尾的分支是什么。我怎么能覆盖它们?
【问题讨论】:
这个函数末尾的分支是什么。我怎么能覆盖它们?
【问题讨论】:
作为超级简单的答案,分支表示IF/ELSE 分支。所以对于每一个 if/else 都有两个新的分支(应该被覆盖);如果嵌套,则呈指数增长。
function twoNewBranches() {
if () {
// code
} else {
// code
}
}
function twoNewBranchesNotAparent() {
if () {
// code
}
}
function fourNewBranches() {
if () {
if () {
// code
} else {
// code
}
}
}
• 第一个函数 twoNewBranches 创建了两个需要覆盖的新分支
• 第二个函数 twoNewBranchesNotAparent 也创建了两个新分支,因为您仍然需要覆盖不满足 if 语句的测试
• 第三个函数fourNewBranches 创建四个(2^2=4) 新分支来覆盖。两个嵌套,嵌套的父级和隐藏的else。
总体记住覆盖分支,就是覆盖条件语句。
【讨论】:
我在 void 函数中没有覆盖的端括号也有同样的问题;
我找到了两种解决方法:
首先将 endbracket 添加到最后一个函数调用行,这样它们就不会显示为单独的行
秒及更好:添加随机“return;”在函数末尾强制执行代码
【讨论】:
您正在观察 gcc 生成的代码,用于破坏静态存储持续时间(全局)变量。
您的报道显示函数foo 已被输入了 3 次,但是范围末尾附近的计数器显示代码已执行了 8 次,包括您查询的分支。
现在您必须考虑编译器将头文件放在翻译单元中,并且 gcov 不会完全按照原样看到您的代码,而是作为汇编指令的控制流图,分支作为图的边缘.
因此,lcov html 输出中的“foo 范围的结尾”并不是真正的 foo 方法范围的结尾,而是包含在 foo 之后以及整个翻译单元中的所有内容,包括销毁已在头文件中声明的全局变量。
标题本身没有包含在问题中,但即使是 gcc 生成的最基本的__static_initialization_and_destruction 程序集也包含许多分支。
请注意,您可能已包含全局变量,也可能未包含 - gcc 仍可能为每个翻译单元生成此代码。
查看gcov的底层输出:
function _Z3fooi called 1 returned 100% blocks executed 50%
1: 4:int foo(int x) {
1: 5: if (x==1) {
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 6: std::cout << "foo" << std::endl;
call 0 never executed
call 1 never executed
#####: 7: return 0;
-: 8: }
1: 9: return 1;
function _GLOBAL__sub_D__Z3fooi called 1 returned 100% blocks executed 100%
function _GLOBAL__sub_I__Z3fooi called 1 returned 100% blocks executed 100%
function _Z41__static_initialization_and_destruction_0ii called 2 returned 100% blocks executed 100%
6: 10:}
call 0 returned 100%
call 1 returned 100%
branch 2 taken 50% (fallthrough)
branch 3 taken 50%
branch 4 taken 100% (fallthrough)
branch 5 taken 0%
-: 11:
并查看生成的程序集,修剪以阐明要点:
...
ret
.seh_endproc
.def _Z41__static_initialization_and_destruction_0ii; .scl 3; .type 32; .endef
.seh_proc _Z41__static_initialization_and_destruction_0ii
_Z41__static_initialization_and_destruction_0ii:
.LFB978:
...
mov QWORD PTR __gcov0._Z41__static_initialization_and_destruction_0ii[rip], rax
cmp DWORD PTR 16[rbp], 1
jne .L5 <-- BRANCH
mov rax, QWORD PTR __gcov0._Z41__static_initialization_and_destruction_0ii[rip+8]
add rax, 1
mov QWORD PTR __gcov0._Z41__static_initialization_and_destruction_0ii[rip+8], rax
cmp DWORD PTR 24[rbp], 65535
jne .L5 <-- BRANCH
...
.L5:
cmp DWORD PTR 16[rbp], 0
je .L6 <-- BRANCH
【讨论】:
} // LCOV_EXCL_LINE
delete 声明的情况是否相同?我得到了一个错过的分支,例如:136 [ + - ]: 45 : delete seq;