编译器会读取代码并优化随机内存分配吗?

时间:2018-10-06 17:06:44

标签: c compiler-optimization

我有一个代码,我在其中声明了一个名为 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->nexthttps://pasteboard.co/HHe7dF8.png

1 个答案:

答案 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)进行测试,因为将寄存器的内容测试为零通常来说,这是一个非常便宜的测试,并且实际上如果该赋值设置了零标志,甚至可能不需要测试,这可能取决于体系结构。

这里的重点是-请勿调试优化的代码,除非未优化的版本有效且优化的版本无效(这可能由于各种问题而发生)。

好运。