我有一个代码,我在其中声明了一个名为 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;
块之前,我看到已删除的地址实际上与curr->next
相同。
编译器这样做是为了优化代码,还是看不到明显的东西?
这是调试到声明已删除时的外观。 https://pasteboard.co/HHe6eQE.png
这是调试屏幕,您可以在其中看到curr->next
。
https://pasteboard.co/HHe7dF8.png
答案 0 :(得分:2)
如果您使用-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
拉至声明点,然后针对寄存器var removed
对NULL(0)进行测试,因为将寄存器的内容测试为零通常来说,这是一个非常便宜的测试,并且实际上如果该赋值设置了零标志,甚至可能不需要测试,这可能取决于体系结构。
这里的重点是-请勿调试优化的代码,除非未优化的版本有效且优化的版本无效(这可能由于各种问题而发生)。
好运。