Live data from Hacker News

Mysterious Moving Pointers

blomqu.ist

61–68 of 68 posts

Re: Mysterious Moving Pointers

#61

I must be misunderstanding something from this article. With: struct Node { std::vector connections; }; struct Connection { Node* from, to; }; Does this mean that to create the vector of connections, Nodes are created, and references are taken to store in the Connections? And then the Nodes are stored in the list, with std::move()? I don't understand why you would want to go down that road. Intuitively, I would assum…

I don't think you're misunderstanding, it's a strange choice to make even if the example here loses context to make it easier to make the point. It wasn't code that anyone currently here wrote and because it worked with the old compiler, nobody really touched it. I believe the nodes are pushed into the list before adding connections but I don't think that changes the point you're trying to make. That said, one's intu…

Thank you for the clarification!

> It may make more sense to create pointers here but that's a larger change to deal with and ensure correctness versus just swapping the vector out for another list. I don't claim to like that solution but it seems to me like legacy C++ code in general is fragile enough as it is,

That's more than fair enough. In such code, more often than not, you make what you think is a small change, and you end up with an entire cascade of unexpected side-effects that pop-up because the original assumptions and the testing scope of those assumptions were lost. A can of worms best left unopened.

By the way, wouldn't such an error be something that gets detected by the "new" ASAN functionality that has been added to the newer MSVC toolchain you are using?

Re: Mysterious Moving Pointers

#62

IMHO this is another case where C++'s hidden layers of complexity hides bugs that would've been obvious in plain C. In fact for this particular use-case I'd probably use indices instead of pointers.

I remember the C++ ca. 1994 year when I started my career. It was C with Objects back then. And it was great! C++ was better C, it was easy for any C dev to convince him/her to jump to it. I recently had to work with C++ code and... it is not a happy story anymore: - Lots of magic like described here - F**ing templates - for those who like them, did you ever see a C++ core file? Or tried to understand a single symbol…

Templates as in C++ are a historical accident.

Erwin Unruh demonstrated to the C++ commitee how they had accidentally created a second, compile time programming language inside the primary language. He did this by calculating primes and printing them in error messages.

People got carried away a bit with the power made available by this new language. Unfortunately there are no basic ergonomics in template metaprogramming because it was not intended to be a programming language.

Re: Mysterious Moving Pointers

#63

Earlier quoted context omitted.

> - F*ing templates - for those who like them, did you ever see a C++ core file? Or tried to understand a single symbol? I have 20+ years of experience writing C++. Yes, I've looked at "core" C++ headers and source. The most annoying part to me is style (mixed tabs and spaces, curly braces at wrong places, parenthesis or not, the usual style complaints). But other than that they're very readable to a seasoned C++ eng…

>> - F ing templates - for those who like them, did you ever see a C++ core file? Or tried to understand a single symbol?* > I have 20+ years of experience writing C++. > Yes, I've looked at "core" C++ headers and source. https://en.wikipedia.org/wiki/Core_dump

Ahh, core dump, not "core" file. Ok, slightly ambiguous and I feel sheepish about it.

I've also looked at core files in GDB, not directly. They're about as unintelligible as a core dump from a C program. It all depends on -fno-omit-frame-pointer: with it, it's usable. Without it, good luck because it involves un-convoluting the optimizer. That's both for C and C++.

Re: Mysterious Moving Pointers

#64
post #48

Earlier quoted context omitted.

So you don't know how much to allocate and you also don't want to allocate too much. It sounds like you want something built on top of std::vector but with your own rules about when to reserve() and how much.

No, for the use cases I'm thinking of, I really do just want an intrusive linked list. Why would I want to invent a convoluted way to adapt std::vector when an intrusive linked list does exactly what I want? (Example use case: Some number of objects want to register themselves as observers on some event, and unregister themselves later, in arbitrary order. The same object may register and unregister itself many times…

Let me remind you what you said which I quoted:

> I want to be able to dynamically add and remove objects from the list without any allocations at all. The only way to achieve that is an intrusive linked list design

So with that, let me reply to your most recent comment:

> No, for the use cases I'm thinking of, I really do just want an intrusive linked list. Why would I want to invent a convoluted way to adapt std::vector when an intrusive linked list does exactly what I want?

You said an intrusive linked list is the only way to achieve that design. I'm telling you it's not the only way to implement a zero-allocation linked list.

If an intrusive linked list is exactly what you want then great for you. You haven't clearly articulated exactly why you must have an intrusive linked list. I've given you an alternative. You're rejecting it out-of-hand because you don't want to "invent a convoluted way to adapt" already-existing containers.

> Why would I want to invent a convoluted way...

You only think it's convoluted. I argue that it's not convoluted at all.

There are many reasons you would not always be able to use an intrusive linked list. Intrusive linked lists are... intrusive. They require that you:

- directly modify T (again, might not be possible if you don't own the code for T, eg it comes from a third party library)

- or have T as a member (which also might not be possible, particularly whether T must be created by a factory and how convoluted that factory is)

- or else have capability to inherit from T (which might not be possible, see `final` keyword).

You haven't stated any of these (or any other) reasons. You simply stated that an intrusive linked list is the "only" way to achieve zero-allocation linked lists. Without stating why you must have an intrusive list, I have merely offered another option. If you think using the standard library is convoluted here then I wonder what other data structure concepts you will have trouble understanding and suggest that C++ isn't the right language for you.

Re: Mysterious Moving Pointers

#65

Earlier quoted context omitted.

UB is a feature; people who keep on fighting it are such a pain. Regarding your question, nothrow operations are essential to maintaining invariants. And maintaining invariants is how you make code correct in a world where UB exists.

Yes, if the programmer maintains certain invariants, the C's flavour of UB allows the compiler to take advantage of those invariants for performance gains, by omitting run-time checking for those invariants. The problem with this flavour of UB being a programmer's promise "this is fine, trust me, no run-time checks needed" to the compiler is that a) it's made by the programmer by omitting said run-time checks ― and t…

A program's correctness goes way beyond memory safety, and is entirely at the mercy of thr programmer doing a good job.

This is true regardless of whether the language has undefined behaviour or not.

Re: Mysterious Moving Pointers

#66

This is a noob mistake, not a huge mystery. It's not always wrong to store raw pointers to STL container elements, but if you do then you must take care of reallocations. If you find storing pointers to elements too perilous, you should probably just make a container of pointers instead.

> This is a noob mistake, not a huge mystery.

The interesting part is why it worked in VS2013 but failed in VS2022.

Re: Mysterious Moving Pointers

#67
post #66

This is a noob mistake, not a huge mystery. It's not always wrong to store raw pointers to STL container elements, but if you do then you must take care of reallocations. If you find storing pointers to elements too perilous, you should probably just make a container of pointers instead.

> This is a noob mistake, not a huge mystery. The interesting part is why it worked in VS2013 but failed in VS2022.

>The interesting part is why it worked in VS2013 but failed in VS2022.

I thought the explanation he came up with was interesting but such a change could have easily been brought about by changes to reallocation parameters in the implementation.

Post reply on HN