Reputation: 41
I have a code where I declare a pointer (named "removed") in type of a struct called 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 just returns the starting point of the double linked list. So removed will be the head of the list.
When I debug the code, dlinked_list_goto_idx returns the list itself (which is the starting node) and I can see it's address. Then removed is declared and again I see the address of it.
Before I execute the removed = curr->next;
block I see that the address of removed is actually identical to curr->next
.
Does compiler do this to optimize the code or I cannot see an obvious stuff?
This is how it looks when I debug to the point where removed is declared. https://pasteboard.co/HHe6eQE.png
And this is the debug screen where you can see the curr->next
.
https://pasteboard.co/HHe7dF8.png
Upvotes: 1
Views: 58
Reputation: 50017
If you're compiling with anything except -O0
or its equivalent - i.e. "no optimizations" - the compiler may very well be rewriting your code as:
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);
}
In other words, it may have chosen to pull removed = curr->next
up to the point of declaration and then test for NULL (0) against the register var removed
because testing the contents of a register for zero is generally a pretty cheap test, and may in fact not even require a test if the zero flag is set by the assignment, which it might be depending on the architecture.
The point here is - don't debug optimized code, unless the non-optimized version works and the optimized version doesn't (which can happen due to various issues).
Best of luck.
Upvotes: 2