This seems like the classic argument of whether approaches like Duff's Device[1] are a good implementation idea. I would offer that there is no shame in doing something a bit more advanced, as long as there are test cases and documentation proportional to the advanced nature of the technique available. [1] https://en.m.wikipedia.org/wiki/Duff's_device
Linus Torvalds' good taste argument for linked lists, explained
121–130 of 339 posts
Re: Linus Torvalds' good taste argument for linked lists, explained
#122Earlier quoted context omitted.
Question for experienced C programmers (I'm not one). The comments for remove_list_entry strike me as fluff, only suitable for a didactic piece. Would you find the comments in the second version helpful, or should they also be removed? Edit: let me lay my cards on the table. If the comments really are necessary, it doesn’t seem elegant. I’m pro-comments, but that’s because not all code can be readable and elegant all…
The top pattern is extremely common so comments are somewhat unnecessary since everyone would know what you're doing. In the second one, comments would be less necessary with a type annotation and perhaps a better name. Maybe "next_ptr" instead of "indirect"---all pointers are indirection, so that name is redundant. But the comments are necessary, to me at least.
Re: Linus Torvalds' good taste argument for linked lists, explained
#123Lastly my link object contained 5 pointers, so I XORed the object and box pointer to cut it down to 4. I always start traversal from one of those, so the XORed value can always be used to reach the other. This did not really impact performance much.
Re: Linus Torvalds' good taste argument for linked lists, explained
#124> it is not immediately evident how the more elegant solution actually works
another virtue is ease of comprehension, and the more elegant solution lacks that in my (and seemingly Linus') opinion. Maybe if you're used to working with pointers to pointers you might have an intuituon for them, but I at least had a difficult time gaining an intuitive grasp on the second solution, which could potentially nullify the bug-resistance of having fewer branching cases. In short, calling the second one objectively better is overstating it I think.
It's worth noting that in a language with union types, you can have the best of both worlds (using Rust here because it's the one I'm most familiar with):
enum LinkedList {
Null,
Node { value: i32, next: Box }
}
In the same way that the pointer to a pointer homogenizes the head-case with the rest, a union type means that any given linked list "is just a node", and the head can therefore be treated the same way as any later nodeRe: Linus Torvalds' good taste argument for linked lists, explained
#125By using the pointer to the current element, you lose information (that element's ancestor), forcing you to introduce a "prev", and to track and update 2 variables.
By using a pointer to the pointer of the current element, you have access to all the information you need -- the "prev" and the "cur" -- just by following the pointer trail one or two steps.
Re: Linus Torvalds' good taste argument for linked lists, explained
#126The second version seems more elegant but will scare non-C people away with all those pointers ;-) What I do not understand is why one should use an "IntList" struct in the first place? As the explanation of the second method suggests, a List is the same thing as a pointer to its first element, so why not do this?: typedef struct IntListItem* IntList; Also, could it be that both methods fail terribly (infinite loops?…
Um, yes. That jumped out at me. If there's a no-find, the code will de-reference null and crash. That's just not acceptable. Try to write that in Rust, using Some(ref) for the forward link, and the compiler will force you to test for None and detect the end of the list. This is pre-1990s programming style. I've seen such code in assembly programs. Because I was reading crash dumps where it failed.
(separate code exists for searching a list)
This... is not Python. C programmers, particularly kernel developers, have that style even in 2020.
Re: Linus Torvalds' good taste argument for linked lists, explained
#127I'm not sure why the article removed comments from the code and replaced variable names like "indirect" with "p". Here are the two code samples verbatim from Linus's presentation: remove_list_entry(entry) { prev = NULL; walk = head; // Walk the list while (walk != entry) { prev = walk; walk = walk->next; } // Remove the entry by updating the // head or the previous entry if (!prev) head = entry->next; else prev->next…
Perfect. I almost commented to complain that the “elegant” version is harder to read and understand. This is much much better. Comments are important!
Usually variable names in a loop is the object being manipulated not the address of that pointer which means p isn't a pointer to the object which makes it completely confusing.
If the article used pp which is the typical way you describe a pointer to pointer it'd help
Re: Linus Torvalds' good taste argument for linked lists, explained
#128Earlier quoted context omitted.
There's arguments to be made on both sides, but I think the problem with Linus's solution here is that it doesn't quite clearly establish the assumption being made, which gives it a bit too much of the 'cleverness' flavor that you allude to. A better implementation would be one that does establish why the use of pointers make sense: void remove_entry(node_t *entry) { // curr_ref is the address of the link pointing to…
That does make it a bit clearer, but I do hope the compiler optimizes away the redundant curr variable. Now, on a different note, I am a bit puzzled because I don’t see a free(*ptr) call in Linus’ or anyone else’s code. The code, as-is, would cause a memory leak. There’s a need to capture the curr_ref before it’s overwritten, and free it after it’s overwritten.
Re: Linus Torvalds' good taste argument for linked lists, explained
#129I understand the general point (and value) of reframing the problem or the solution in a way that removes special cases ... but in this case I would actually prefer the first solution over the second. The second solutions reminds me of the old-school perl culture, and JavaScript culture, where 'cleverness' (which always manifests itself as terseness as if lines of code were expensive), takes precedence over maintaina…
[1] https://www.cs.utexas.edu/users/EWD/transcriptions/EWD07xx/E... and https://www.google.com/search?q=site%3Ahttps%3A%2F%2Fwww.cs.... for more
Re: Linus Torvalds' good taste argument for linked lists, explained
#130Earlier quoted context omitted.
A tool can write the name for you once, but you have to reread it many times and we don’t have a tool to help with that.
That's not how reading works. You don't parse every character like a computer does. You look at the starting letter (maybe the ending one too) and then recognize the shape of the word used. There isn't too much difference in reading a long or short variable name as long as there aren't variable names that are too similar to one another.
theDependentVariable = theCoefficient * theIndependentVariable + theIntercept
it is much harder to recognize than if I write: y = a*x + b
So, longer variable names might be "autodocumenting" but they also make code harder to read.