我可以向您解释控制流图的概念,但我对库本身并不熟悉。
这个概念很简单。将任何连续的代码行(即没有if
、goto
或函数调用或标签)想象为图的一个节点。每个goto
或函数调用都会创建从当前节点到goto
标签所在节点或它正在调用的函数的定向链接。请记住,函数本身可以是图而不是简单的节点,因为它if
内部可能有 s 或其他函数调用。每个函数调用还创建从函数的叶节点(函数return
s 所在的位置)到函数调用后包含代码的节点的定向链接。(这可以创建很多从函数图传出的链接,因为该函数可以在代码的许多部分中调用)
同样,如果您有,则从当前节点到语句的部分和部分if
都有两个方向链接(除非您检测到或像您说的那样,在这种情况下只有一个链接到正确的位置)if
else
if
if(0)
if(1)
图的根是 的入口点main
。现在,要找到死代码,您必须做的是简单地从根位置遍历图(例如使用 DFS 或 BFS),最后查看哪些节点未被访问。这向您显示了死代码,即代码中的位置,无论您的程序采用什么方向,它都不会到达这些位置。
如果你想自己实现这个,你可以采取递归的方法(类似于解析代码但更简单)。例如,如果你看到一个if
你说:
typedef char *line;
FlowGraph *get_flow_graph(line *code)
{
FlowGraph *current_node = malloc(sizeof *current_node);
current_node->flow_to = malloc(some_maximum * sizeof *current_node->flow_to);
current_node->flow_to_count = 0;
...
if (is_if_statement(code[0]))
{
FlowGraph *if_part = get_flow_graph(code + 1);
FlowGraph *else_part = get_flow_graph(code + find_matching_else(code));
current_node->flow_to[current_node->flow_to_count++] = if_part;
current_node->flow_to[current_node->flow_to_count++] = else_part;
}
else
...
}