我有一个代码,其中我声明了一个指针(名为“removed”),类型是一个名为DLINKED_LIST_NODE的结构。

DLINKED_LIST_NODE curr = dlinked_list_goto_idx(list, idx, false);
DLINKED_LIST_NODE removed;

if(curr->next != NULL)
    removed = curr->next;
else {
    printf("Error @ dlinked_list_remove: No such index.\n");
    exit(1);
}

dlinked_list_goto_idx只返回双链接列表的起点。所以被除名的将是名单上的头名。
当我调试代码时,dlinked_list_goto_idx返回列表本身(这是起始节点),我可以看到它的地址。然后删除是声明和再次我看到它的地址。
在执行removed = curr->next;块之前,我看到removed的地址实际上与curr->next相同。
编译器这样做是为了优化代码,还是我看不到明显的东西?
这就是我调试到声明remove时的样子。
https://pasteboard.co/HHe6eQE.png
这是调试屏幕,您可以在其中看到curr->next
https://pasteboard.co/HHe7dF8.png

最佳答案

如果您使用除-O0或其等效项(即“无优化”)以外的任何其他方法进行编译,编译器很可能会将您的代码重写为:

register DLINKED_LIST_NODE curr = dlinked_list_goto_idx(list, idx, false);
register DLINKED_LIST_NODE removed = curr->next;

if(removed == 0) {
    printf("Error @ dlinked_list_remove: No such index.\n");
    exit(1);
}

换言之,它可能选择将removed = curr->next拉到声明点,然后针对寄存器varremoved测试NULL(0),因为测试寄存器的内容for zero通常是一个非常便宜的测试,而且如果通过赋值设置了zero标志,实际上甚至可能不需要测试,这可能取决于体系结构。
这里的要点是-不要调试优化的代码,除非非优化版本可以工作,而优化版本不能工作(这可能是由于各种问题造成的)。
祝你好运。

07-28 02:53
查看更多