Live data from Hacker News

The repercussions of missing an Ampersand in C++ and Rust

nablag.com

51–60 of 128 posts

Re: The repercussions of missing an Ampersand in C++ and Rust

#51

Earlier quoted context omitted.

When I looked into the history of the C++ move (which after all didn't even exist in C++ 98 when the language was first standardized) I discovered that in fact they knew nobody wants this semantic. The proposal paper doesn't even try to hide that what programmers want is the destructive move (the thing Rust has) but it argues that was too hard to do with the existing C++ design so... The more unfortunate, perhaps dis…

> When I looked into the history of the C++ move (which after all didn't even exist in C++ 98 when the language was first standardized) I discovered that in fact they knew nobody wants this semantic. The proposal paper doesn't even try to hide that what programmers want is the destructive move (the thing Rust has) but it argues that was too hard to do with the existing C++ design so... > The more unfortunate, perhaps…

Now that would be a cool first proposal and implementation. I wonder if there’s any prior art in C++ yet.

Re: The repercussions of missing an Ampersand in C++ and Rust

#53
post #27

As someone who programs both C++ and Rust, without even reading the article, my own experience with typos in those languages is: Rust: Typo? Now it just doesn't compile anymore. Worst case is that the compiler does a bad job at explaining the error and you don't find it immediately. C++: Typo? Good luck. Things may now be broken in so subtle and hard to figure out ways it may haunt you till the rest of your days. But…

> Worst case is that the compiler does a bad job at explaining the error and you don't find it immediately.

By the way, the project considers this a bug and accepts reports for that. In many occasions they are easy to fix. In others large refactors are needed. But being aware of the case is the necessary first step to making them better.

Re: The repercussions of missing an Ampersand in C++ and Rust

#54
post #19

> There are plenty of linters and tools to detect issues like this (ex: clang-tidy can scan for unnecessary value params) Exactly, this is not an issue in any reasonable setup because static analysis catches (and fixes!) this reliably. > but evidently these issues go unnoticed until a customer complains about it or someone actually bothers to profile the code. No

This is my gripe with C++ - I have to have a CI pipeline that runs a job with clang-tidy (which is slow), jobs with asan, memsan and tsan, each running the entire test-suite, and ideally also one job for clang and one for gcc to catch all compiler warnings, then finally a job that produces optimized binaries. With Rust I have one job that runs tests and another that runs cargo build --release and I'm done...

That's a pretty heavy setup. Clang tidy is usually enough. And not slow when running locally on newly typed code in resharper for example.

Re: The repercussions of missing an Ampersand in C++ and Rust

#55
This is why the D programming language uses the keyword `ref` rather than the ampersand. Too many overlooked misteaks with the latter.

It extends it a bit, too, with `out` meaning that the referenced argument is initialized by the function, not read.

Re: The repercussions of missing an Ampersand in C++ and Rust

#56

Earlier quoted context omitted.

> The destructor already has to deal with that. That's partly true, partly circular. Because moves work this way, it's harder to make a class that doesn't have empty states, so I don't design my class to avoid empty states, so the destructor has to handle them.

Please give me an example for a class that needs to handle empty state in the destructor only because of move operations. These exist, but IME they are very rare. As soon as you have a default constructor, the destructor needs to handle the case of empty state.

This means C++ is riddled with types that have unrelated "I'm empty" state inside them rather than this being relegated to a separate wrapper type. It's Tony's Billion Dollar Mistake but smeared across an entire ecosystem.

The smart pointer std::unique_ptr is an example of this, sometimes people will say it's basically a boxed T, so analogous to Rust's Box but it isn't quite, it's actually equivalent to Option>. And if we don't want to allow None? Too bad, you can't express that in C++

But you're right that C++ people soldier on, there aren't many C++ types where this nonsense unavoidably gets in your face. std::variant's magic valueless_by_exception is such an example and it's not at all uncommon for C++ people to just pretend it can't happen rather than take it square on.

Re: The repercussions of missing an Ampersand in C++ and Rust

#57
> Granted, these repercussions of these defaults also result in (in my opinion) verbose language constructs like iter, into_iter, iter_mut ↩

Note that assuming the into_iter comes from IntoIterator that’s what the for loop invokes to get an iterator from an iterable. So

    for lr in LoadRequests.into_iter() {
Is completely unnecessary verbosity,

    for lr in LoadRequests {
Will do the exact same thing. And the stdlib will generally implement the trait with the relevant semantics on shared and unique references so

    for lr in LoadRequests.iter_mut()
Can generally be written

    for lr in &mut LoadRequests
So you rarely need to invoke these methods outside of functional pipelines if you dislike them (some prefer them for clarity / readability).

Re: The repercussions of missing an Ampersand in C++ and Rust

#58

Earlier quoted context omitted.

Please give me an example for a class that needs to handle empty state in the destructor only because of move operations. These exist, but IME they are very rare. As soon as you have a default constructor, the destructor needs to handle the case of empty state.

This means C++ is riddled with types that have unrelated "I'm empty" state inside them rather than this being relegated to a separate wrapper type. It's Tony's Billion Dollar Mistake but smeared across an entire ecosystem. The smart pointer std::unique_ptr is an example of this, sometimes people will say it's basically a boxed T, so analogous to Rust's Box but it isn't quite, it's actually equivalent to Option >. And…

(And that difference leads to an ABI difference that makes it not a zero overhead abstraction in the way that Box is…)

Re: The repercussions of missing an Ampersand in C++ and Rust

#60
post #38

Earlier quoted context omitted.

This was one of the most unsatisfying things about learning C++ move semantics. They only kinda move the thing, leaving this shell behind is a nightmare.

Since I use move semantics all the time, this is for me the most frustrating thing about C++ full stop. I really wish they'd fix this instead of adding all those compile-time features.

How would you fix this in C++?
Post reply on HN