Live data from Hacker News

Mysterious Moving Pointers

blomqu.ist

31–40 of 68 posts

Re: Mysterious Moving Pointers

#31
post #4
post #2

I know C++ the language but not the STL (the overwhelming abundance of UB and total lack of safety make it an anathema), so my question is why the STL allows/requires non-move here copying here dependent on whether an object has a no throw move constructor? Note I’m not asking about move constructor vs memmove/cpy but rather the use of copy constructor vs move depending on exception behavior? Is it something like pre…

What do you use instead of std::vector, map, unique_ptr, etc? I have a hard time thinking of C++ and the STL as separate. Even our internal utilities and such tend to be STL-like although often with safer defaults.

Lots of the C++ standard library, including the STL containers isn't provided in freestanding C++. Now, in reality freestanding C++ has been kind of a joke - the committee for years barely bothered to keep it working - especially compared to freestanding C (which is well defined and used all over the place) and say Rust no_std (likewise) - and so many embedded systems may have the entire standard library notionally available even though parts of it are definitely nonsense for them and they've got local rules saying not to use the parts that would definitely explode in their environment... but many C++ programmers who have worked under such rules just reflexively avoid the STL's containers and maybe its algorithms even in an environment where those would work.

Re: Mysterious Moving Pointers

#32

Earlier quoted context omitted.

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…

> I remember the C++ ca. 1994 year when I started my career. It was C with Objects back then It is possible, and perhaps even likely that the C++ you wrote in 1994 was indeed this "better C" and maybe even the C++ you read, the language Stroustrup wrote about in 1985 although "C with Objects" is much older still. The ISO document (C++ 98 aka ISO 14882:1998) was four years into your future in 1994, but the committee t…

I believe that not many developers really wanted C++ and craved Object Pascal instead.

I don't like Pascal but I have to admit that Object Pascal is a succint and successful addition of OO to a manually memalloc language, whereas C++ is neither.

Re: Mysterious Moving Pointers

#33
post #25

Earlier quoted context omitted.

> Perhaps you could use some sort of weak pointer that gets nulled out when the target object is destroyed std::shared_ptr comes with std::weak_ptr. Referencing counting is rather ham-fisted approach but is certainly a solution. > IMO the language-level problem, if there is one, is that C++ is too willing to copy in cases where you would expect it to move instead. IMO that's not a problem in the language but a proble…

Agreed that std::list is never the best solution. In every case where I want linked list semantics, it's because 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, which std::list is not...

> 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

No it isn't.

    std::array>>, 256U /* or whatever your maximum size is \*/>.
Indexing does come with a wart: you'd need a sentry value for a "no prev" or "no next" value, I'd just use std::numeric_limits::max() for that. And of course when you move objects within the container you'd need to update the indices.

If you don't know your upper size bound at compile time, then replace `array` with `vector`, and reserve your runtime-known upper bound. As long as you never violate your upper bound then no (re-)allocations occur (unless T's constructor allocates).

Re: Mysterious Moving Pointers

#34
post #2

I know C++ the language but not the STL (the overwhelming abundance of UB and total lack of safety make it an anathema), so my question is why the STL allows/requires non-move here copying here dependent on whether an object has a no throw move constructor? Note I’m not asking about move constructor vs memmove/cpy but rather the use of copy constructor vs move depending on exception behavior? Is it something like pre…

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.

Re: Mysterious Moving Pointers

#35

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…

boost is just awful. Don’t use boost.

templates are totally fine for basic containers. Much better than C macro shenanigans.

The world is still looking for a “better C”. Zig, Odin, Jai and probably more are all trying. Of the three I think Jai is the closest. But it’ll be awhile.

Re: Mysterious Moving Pointers

#36
post #4
post #2

I know C++ the language but not the STL (the overwhelming abundance of UB and total lack of safety make it an anathema), so my question is why the STL allows/requires non-move here copying here dependent on whether an object has a no throw move constructor? Note I’m not asking about move constructor vs memmove/cpy but rather the use of copy constructor vs move depending on exception behavior? Is it something like pre…

What do you use instead of std::vector, map, unique_ptr, etc? I have a hard time thinking of C++ and the STL as separate. Even our internal utilities and such tend to be STL-like although often with safer defaults.

Essentially the same things but reimplemented safely - see WTF in webkit.

There are still issues (the iterator API used by for(:) is very hard to make safe without terrible perf issues, though I was looking at this recently and the compilers are doing much better than they used to).

Things like unique_ptr and shared_ptr do not meaningfully improve the security of c++ despite being presented as if they did (all serious c++ projects already had smart pointers before the stl finally built them in so presenting them as a security improvement is disingenuous), and because of the desire to have shared_ptr be noninvasive it’s strictly worse than most other shared ownership smart pointers I’ve used.

Re: Mysterious Moving Pointers

#37
post #25

Earlier quoted context omitted.

Agreed that std::list is never the best solution. In every case where I want linked list semantics, it's because 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, which std::list is not...

> 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 No it isn't. std::array >>, 256U /* or whatever your maximum size is \*/>. Indexing does come with a wart: you'd need a sentry value for a "no prev" or "no next" value, I'd just use std::numeric_limits ::max() for that. And of course when you move obje…

In most (quite possibly all) cases I don't know the upper bound even at runtime. So, this ends up requiring allocation.

Re: Mysterious Moving Pointers

#38

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…

> - 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++ engineer.

I've also tried to understand symbols. You're right, they're difficult. But there's also tooling available to do it automatically. Even if you don't want to use the tools, there is a method to the madness and it's documented...

Let me ask ChatGPT:

> What tool lets me translate an exported symbol name to a C++ name?

    C++filt
It's categorized as a demangler. That's your search term to look for (I had to remember what it was).

Then I asked:

> Is there a function in the standard library which allows to mangle or demangle a given name or symbol?

It tells about `__cxa_demangle` for GCC. While I had forgotten about that, I'm pretty sure there is (or perhaps something similar) in the standard library.

It also suggests to use a library such as `abi::__cxa_demangle`. Hah, that's what I was looking for. It's an implementation-specific API (eg, compiler-specific) API used as an example. It was mentioned on `std::type_info::name()` page here:

https://en.cppreference.com/w/cpp/types/type_info/name

So, to continue replying to you: yes, it's annoying but it's solvable with tools that you can absolutely integrate into your IDE or command-line workflow.

> - Standarization that feels like pulling more Boost into the language, which means more templates.

The boost libraries are open source and their mailing lists are active. If you don't like a given library because it has too many templates then you could make one with fewer templates.

And, as standardization goes, it's also quite open source. The C++ committee is very open and receptive to improvements. The committee are volunteers (so their time is limited) and (usually) have their own improvements to the standard that they want. So you have to drive the changes you want (eg, actively seek feedback and engagement).

> P.S. Example from recent core file, one line in the stack trace:

I've seen much longer -- I've seen templates entirely fill a terminal buffer for a single line. That's extremely rare, definitely not fun, and debuggability is absolutely a valid reason to refactor the application design (or contribute library changes).

I find it useful to copy the template vomit into a temporary file and then run a formatter (eg clang-format), or search/replace `s/(Some debuggers also understand type aliases. They'll replace the aliased type with the name you actually used, and then separately emit a message (eg, on another line) indicating the type alias definition (eg, so you can see it if you don't have a copy of the source)

Re: Mysterious Moving Pointers

#39
post #37

Earlier quoted context omitted.

> 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 No it isn't. std::array >>, 256U /* or whatever your maximum size is \*/>. Indexing does come with a wart: you'd need a sentry value for a "no prev" or "no next" value, I'd just use std::numeric_limits ::max() for that. And of course when you move obje…

In most (quite possibly all ) cases I don't know the upper bound even at runtime. So, this ends up requiring allocation.

You don't think it's useful to calculate some reasonable upper bound if only to avoid resource exhaustion?

Re: Mysterious Moving Pointers

#40
post #28
post #16

Earlier quoted context omitted.

The good news is that since C++ containers aren't special to the language, you can just implement your own wrapper classes that disable the copy ctor (and provide an explicit `.clone()` instead). Coupled with `#pragma GCC poison` it is pretty easy to blacklist legacy footguns in source files at least (though not in headers without some aggressive work). ... and yet, almost all vulnerabilities in C++ code are still wr…

Yeah I pretty much only use my own alternate container implementations (from KJ[0]), which avoid these footguns, but the result is everyone complains our project is written in Kenton-Language rather than C++ and there's no Stack Overflow for it and we can't hire engineers who know how to write it... oops. [0] https://github.com/capnproto/capnproto/blob/v2/kjdoc/tour.md

Every work place I've worked at has their own container classes for performance reasons.

We did use some C++ standard library but very sparingly. For example, std::unique_ptr was fine, but std::shared_ptr was not because of the way it implicitly stores it's reference, so we had our own implementation that exposed the reference.

When I was doing console games this was a must. You would often have restrictions where the container itself should live in a different area of memory to the items which is much easier to manage with your own classes.

Post reply on HN