4 ms·
> makes the code less clear and requires additional complexities since you can't just jump from a child to its parent by subtracting an offset from its address.
by ghusbands 3y ago
> makes the code less clear and requires additional complexities since you can't just jump from a child to its parent by subtracting an offset from its address.
Wait, so you're saying that code that subtracts an offset from a child node to get to a parent node is clearer and less complex than alternatives?
- groestl 3y ago> Wait, so you're saying that code that subtracts an offset from a child node to get to a parent node is clearer and less complex than alternatives? Parent made me laugh out loud on this.
- jstimpfle 3y agoI hope you've stopped laughing and can read and understand my answer.
- groestl 3y agoPlease, I did not want to offend you personally. It just took me by surprise. I understand your points, even though I'm with your direct reply, all things considered.
- jstimpfle 3y agoThe address offset subtraction thing specifically is used quite a bit in the Linux kernel for example. It allows to combine abstract code with concrete data. For example they define a red-black tree as a graph of just plain nodes. These nodes are totally abstract, they contain only node pointers but no useful data. The code is totally abstract, no need to instanciate anything a dozen times with different offsets and such. You simply wrap the abstract nodes with whatever concrete useful data you fancy. The same approach works for lists and a variety of other data structures. You can get from the abstract link node to the containing struct with a macro: CONTAINER_OF(ptr, containertype, membername). It's easy to use and unlikely to get it wrong.
- jstimpfle 3y agoNot having the address relationship requires additional complexities. To get from the child to the parent, you need to spend an additional reference field, and need to keep it consistent with the other reference. If you embed directly, there's nothing in the relationship of the objects' identities that could ever get consistent. It's a strong guarantee. How do you get from the child to the parent in, say Java? And how do you tell that a child is never swapped out? How do you copy an object that holds, say 4 vec4, vec4 being a struct that itself 4 holds floats? With value types, say in C, it's 1 memcpy and you're done.
- ghusbands 3y agoIn an archaic language like C, it may be clearer. In a modern language, in no way is subtraction of an offset clearer and simpler than almost any alternative. Even in C, as you've mentioned elsewhere, you've had to use macros to make it at all clear, and macros can do anything and are inherently opaque. Many other languages also have newer/different approaches to solve some of these problems, be they subclassing, generics, macros (often safe ones), JITs, or other. They mostly cannot do this as efficiently, but that seems less like a clarity/complexity concern and more like a low-level-programming concern. > How do you get from the child to the parent in, say Java? In Java, you do indeed have to embed mutual pointers and just be careful. As a C user, you must be used to being careful. Even C#, which does allow structs, doesn't have references-to-members that can be turned into references-to-owners. The aforementioned language features like subclassing (for lists) and generics can help. > How do you copy an object that holds, say 4 vec4, vec4 being a struct that itself 4 holds floats? Copying structs as a block works fine in Rust, C++ and C#, along with many other languages. Again, Java is a little more limited in this regard, though I believe they are working on adding value types.
- jstimpfle 3y agoI think we have quite different ideas what complex means. You seem to see a language (C or machine code), which, while based on simple principles, is complex in its behavior, especially if something goes wrong (which should not happen in the first place). I see literally a subtraction operation versus a huge memory safe language framework set up over the same machine, plus a whole lot more user facing surface level source code, just to achieve the same thing.