3 ms·
This is an especially interesting comparison because while it does clearly exhibit the sort of elegance only achievable through the elimination of special cases
by westoncb 8y ago
This is an especially interesting comparison because while it does clearly exhibit the sort of elegance only achievable through the elimination of special cases, it's also a good demonstration of the tradeoffs one sometimes has to make for this purpose.
The second is significantly 'cleaner,' but with pretty bad readability [0]. The first version has excellent readability.
In practice, the way I'd evaluate the two is by looking at how much other code depends on (or at some point may depend on) the piece under consideration. If nothing else or only very little depends on the code, I'll opt for readability; if it's likely to be somewhat foundational and other stuff is going to grow on it, I'll opt for the more abstract, cleaner version, and document thoroughly.
[0] I'm guessing the readability isn't nearly as bad if the first example is using a common C idiom; I don't use C enough to know. My main criterion for judging readability is: how much does the structure of the code match the conception of the algorithm you're starting with. The conception here has to do with navigating links; the pointer stuff is incidental complexity.
- im3w1l 8y agoTo me the main readability problem of the first example is that it does the head check as the last step rather then first step. Meaning we have to consider "wait, when is this null again". The main problem with the last one is that it's not immediately obvious what the "indirect" represents. When it clicks that it is "the pointer to potentially update", it's pretty easy to understand.
- ummonk 8y agoThe 2nd one would be significantly more readable with explicit typing (to make it clear that you're dealing with a pointer to pointer). Though I think putting the head check at the beginning like you said will make the first example very reasonable (and relatively compact too). remove_list_entry(entry) { if (head == entry) { head = entry->next; } else { prev = head; while (prev->next != entry) { prev = prev->next; } prev->next = entry->next; } }