Live data from Hacker News

C++ std::move doesn't move anything: A deep dive into Value Categories

0xghost.dev

111–120 of 220 posts

Re: C++ std::move doesn't move anything: A deep dive into Value Categories

#112
post #76

Earlier quoted context omitted.

I hear this a lot, but I don’t really understand how this manifests in language complexity like the stuff in TFA in practice. Like, I can understand how systems programming requiring programmers to think about questions like “how can I proceed if allocation fails? How does this code work in an embedded context with no heap?” is hard and irreducible. But I can’t understand why a language’s choice to impose complex rul…

The difference is that in C one is supposed to do allocations and deallocations oneself. Then move semantics is just pointer assignment with, of course, the catch that one should make sure one does not do a double-free because ownership is implicit. In C++ ownership is indicated by types so one has to write more stuff to indicate the ownership.

> The difference is that in C one is supposed to do allocations and deallocations oneself

No, you should only use the heap if necessary.

The bigger issue in C is there is no concept of references, so if you want to modify memory, the only recourse is return-by-value or a pointer. Usually you see the latter, before return value optimization it was considered a waste of cycles to copy structs.

In the embedded world, its often the case you won't see a single malloc/free anywhere. Because sizes of inputs were often fixed and known at compile time for a particular configuration.

Re: C++ std::move doesn't move anything: A deep dive into Value Categories

#113
post #100
post #87

Earlier quoted context omitted.

A bit more if we consider the "bugfixing" release that was C++14 :) But yeah it makes sense, given how that was the jumpstart of the whole modernization of the language. I believe it was a big undertake that required the time it took. Still years have passed and footguns keep accumulating... it wouldn't hurt to have a mechanism to optionally drop the old cruft from the language. Otherwise everything stacks on top in…

While I share the sentiment, compare C#14 with C# 1.0, Java 25 with Java 1.0, Python 3.14 with Python 1.0. While C++ might be worse, when you have 300+ doing proposals every three years, others aren't safer from similar churn, even if on smaller volume, and trying to keep backwards compatibility going. And we all know what happened in Python. Also Rust editions contrary to what many think, only cover a specific set o…

> nor there is support for binary libraries.

This is a weird call-out because it's both completely incorrect and completely irrelevant to the larger point.

Rust absolutely supports binary libraries. The only way to use a rust library with the current rust compiler is to first compile it to a binary format and then link to it.

More so than C++ where header files (and thus generics via templates) are textual.

Cargo, the most common build system for rust, insists on compiling every library itself (with narrow exceptions - that include for instance the precompiled standard library that is used by just about everyone). That's just a design choice of cargo, not the language.

Re: C++ std::move doesn't move anything: A deep dive into Value Categories

#114
post #75

Earlier quoted context omitted.

Systems programming in the large is hard, owning the category for decades harder still. Even languages that have tried to fast-follow and disrupt C++ end up looking a lot like C++. There is an irreducible complexity.

I have no problem with systems programming issues. That complexity is essential complexity inherent in the problem itself, regardless of language. I have a problem with C++’s accidental complexity. I find C much more tractable. It certainly has a few of its own footguns, but it has much less accidental complexity.

As the author of the FQA noted (Yosef K-something), in C++ its more the combinations of features which causes so many issues.

And here we see this principle rear its ugly head yet again. In this case, its the combination of exceptions, manual memory allocation and the desire to make things work efficiently - of which the move constructor was developed as a "solution"

Re: C++ std::move doesn't move anything: A deep dive into Value Categories

#115
post #113
post #100

Earlier quoted context omitted.

While I share the sentiment, compare C#14 with C# 1.0, Java 25 with Java 1.0, Python 3.14 with Python 1.0. While C++ might be worse, when you have 300+ doing proposals every three years, others aren't safer from similar churn, even if on smaller volume, and trying to keep backwards compatibility going. And we all know what happened in Python. Also Rust editions contrary to what many think, only cover a specific set o…

> nor there is support for binary libraries. This is a weird call-out because it's both completely incorrect and completely irrelevant to the larger point. Rust absolutely supports binary libraries. The only way to use a rust library with the current rust compiler is to first compile it to a binary format and then link to it. More so than C++ where header files (and thus generics via templates) are textual. Cargo, th…

Rust does, Rust editions do not have a story for them.

Re: C++ std::move doesn't move anything: A deep dive into Value Categories

#116
post #22

> So the standard library plays it safe: if your move constructor might throw (because you didn’t mark it noexcept), containers just copy everything instead. That “optimization” you thought you were getting? It’s not happening. This is a bit of a footgun and clang-tidy has a check for it: performance-noexcept-move-constructor. However, I don't think it's enabled by default!

performance-noexcept-move-constructor is great but it also complains about move assignment operators, which are completely different beasts and are practically impossible to make noexcept if your destructors throw.

Re: C++ std::move doesn't move anything: A deep dive into Value Categories

#117
post #115
post #113

Earlier quoted context omitted.

> nor there is support for binary libraries. This is a weird call-out because it's both completely incorrect and completely irrelevant to the larger point. Rust absolutely supports binary libraries. The only way to use a rust library with the current rust compiler is to first compile it to a binary format and then link to it. More so than C++ where header files (and thus generics via templates) are textual. Cargo, th…

Rust does, Rust editions do not have a story for them.

The story is that it must not matter which edition a library was compiled with - it's the boundary layer at which different editions interoperate with eachother.

Re: C++ std::move doesn't move anything: A deep dive into Value Categories

#118

Earlier quoted context omitted.

Well, no, because CAN take isn't the same as WILL take. Changing something to an rvalue means it'll now match a move constructor, but there is no guarantee a move constructor will be used, even if defined, because you've got classes like std::vector that are picky and are explicitly looking for a noexcept move constructor.

In that sense, std::move() is no different than other passing semantics. Just because you wrote at the call site that you want to pass a copy of your object doesn't mean that the callee will actually make a copy of it.

I'm not sure what you are saying.

If we have foo(std::string a, std string b), and then call it like this:

std::string x;

std::string y;

foo(std::move(x), y);

Then x will be moved into a, and y will be copied into b.

The callee has no say in this - it's just the compiler implementing the semantics of the language.

Re: C++ std::move doesn't move anything: A deep dive into Value Categories

#119
post #32

About 28 years ago, I figured out that I’m just not smart enough to use C++. There are so many foot guns and so much rampant complexity that I can’t keep it all straight. I crave simplicity and it always felt like C++ craved the opposite.

C++ is a universal tool with long history. So yes it makes it very complex for various reasons. However it does not preclude one from being productive. I do not come anywhere close to being expert in C++. Still write software that blows the shit out of competition. I have general understanding how the things work and when I need some particular feature I just look up the efficient way of doing it in whatever language. Not just for C++. I actively use many languages. My goal is to deliver good software and get paid by happy client, not to know every little detail of the tools I use, it is just impossible and serves no useful purpose.

Re: C++ std::move doesn't move anything: A deep dive into Value Categories

#120
You read things like this and, first, you're reminded of Sideshow Bob [1] and it puts Rust concepts in context, namely:

1. Move semantics are to handle ownership. Ownership is a first-class concept in Rust. This is why;

2. C++ smart pointers (eg std::unique_ptr) are likewise to handle ownership and incur a runtime cost where in Rust they are handled by the compiler with no runtime cost. Yes you can "cheat" (eg std::unique_ptr::get) and people do (they have to) but this is a worse (IMHO) version than the much-maligned Rust unsafe blocks;

3. Not only do all features have a complexity cost but that curve is exponential because of the complexity of interactions, in this case move semantics and exceptions. At this point C++'s feature set combined with legacy code support is not just an albatross around its neck, it's an elephant seal; and

4. There's a 278 page book on C++ initialization [2].

My point here is that there are so many footguns here combined with the features of modern processors that writing correct code remains a Herculean (even Sisyphean) task.

But here's the worst part: IME all of this complexity tends to attract a certain kind of engineer who falls in love with their own cleverness who creates code using obscure features that nobody else can understand all the true implications (and likely they don't either).

Rust is complex because what you're doing is complex. Rust isn't a panacea. It solves a certain class of problems well and that class is really important (ie memory safety). We will be dealing with C++ buffer overflow CVEs until the heat death of the Universe. But one thing I appreciate about languages like Go is how simple they are.

I honestly think C++ is unsalvageable given its legacy.

[1]: https://www.youtube.com/watch?v=2WZLJpMOxS4

[2]: https://leanpub.com/cppinitbook

Post reply on HN