0
void inc(int &n) {
    n++;
}

Consider the above function. If I were to call it with an rvalue, C++ would shout at me. For example inc(1).

It seems perfectly reasonable for the standard to have been that a temporary is created, and dropped at the end of the function's execution (as you currently have to manually do).

In fact, other languages already do this. Consider Rust

fn inc(n: &mut i32) {
    *n += 1;
}

Here, calling inc(&mut 1) is perfectly valid.

What is especially interesting is that C++ allows this sort of pattern for const references. So the only function I can imagine this having is to indicate to the caller that they are throwing away an effect of the function. However, we have to explicitly issue at most warnings with [[nodiscard]] for ignored return values...

I am sure I am missing something C++-ish that I don't understand quite yet! What kind of good reasons are there for having the standard be this way, instead of, for example, requiring [[nodiscard]] on parameters like we do with return values?

doliphin
  • 752
  • 6
  • 22
  • 1
    What you are missing is a lot of history `[[nodiscard]]` didn't exist when C++ was first created. let me see If I cant find a post on this – NathanOliver Aug 28 '23 at 18:56
  • here is a good one: https://stackoverflow.com/questions/1565600/how-come-a-non-const-reference-cannot-bind-to-a-temporary-object – NathanOliver Aug 28 '23 at 18:58
  • 2
    Imagine this scenario, `void inc(double& d) { d += 1.0; }`. And you call it with `inc(5);` or with `int i = 5; inc(5);`. If the rule was not enforced, the compiler would silently make a temporary and increment it. Probably a bug. – Eljay Aug 28 '23 at 19:06
  • Can you show a single use-case where this would do something useful? I don't think there's a single case where modifying a temporary can bring a useful behaviour, especially since C++11 came with rvalue references. – Yksisarvinen Aug 28 '23 at 20:28
  • @Yksisarvinen It's not that modifying a temporary is useful if that's all you're doing. The modification of one of the parameters is one of potentially several effects of a function. The other effects of the function may differ depending on this parameter. This is a very common pattern actually. Consider any function of a class that modifies `this` while also returning a value. A struct that contains a counter, for example. – doliphin Aug 28 '23 at 20:43
  • But modifying `this` has nothing to do with passing objects by non-`const` reference. The only reason to pass non-const reference to an object is when you want to modify it. If you need to only read a value, you pass a const reference or a copy. – Yksisarvinen Aug 28 '23 at 20:50
  • In the case where you have some optional return value that the caller might not care about you use a pointer rather than a non-const reference e.g like `std::stoi` – Alan Birtles Aug 29 '23 at 01:08
  • 1
    @doliphin - Apparently Bjarne early on ran into the "update lost" bug often enough to add this special rule to the language. So, at least he saw it as a real problem. – BoP Aug 29 '23 at 10:15

0 Answers0