12

I am going through "C++ Primer", and it is mentioned that for the following code:

double dval = 3.14;
const int &ri = dval; //Bind a const int to a plain double object.

The transformation of the code will be:

const int temp = dval; //Create a temporary const int from the double
const int &ri = temp;  //bind ri to that temporary

So, if I modify dval, say I set it to dval = 3.0, since ri will be bound to the temporary object, the changed value will not be reflected.

Wouldn't this cause a lot of subtle bugs? Why is such a thing allowed? It is not intuitive as a reference.

7
  • 3
    In your alternative C++ the following would not be allowed, void f(const int& ri); f(3.14); because it binds ri to a temporary object. I guess the designers of C++ preferred to allow this construct rather than ban your potential 'subtle bugs'. References as function parameters are common, references as local variables are pretty rare. Commented Aug 9 at 15:47
  • In order to get the behaviour you desire, you would have to somehow keep track of all "converting" references to something and re-convert the value when it changes, or re-convert the value on each access. Neither is feasible. Commented Aug 10 at 9:25
  • I just want to note that setting dval = 3.0 would change nothing about ri even in the hypothetical case where it was updated. Setting dval = 4.0 would be the interesting case as that would have a different corresponding integer conversion. Commented Aug 11 at 15:45
  • Wouldn't this cause a lot of subtle bugs? Yes, it can. Why is such a thing allowed? Not a common pattern in practice. It is not intuitive as a reference. C++ is not a good poster child for being an intuitive language — it strictly adheres to the principle of most surprise to incur the most delight, wonder, and/or job security. Commented Aug 11 at 16:47
  • @mindentropy I wonder if the answer you've gotten is acceptable in its current form or if you're lacking anything from it? Commented Aug 29 at 13:55

1 Answer 1

9

Wouldn't this cause a lot of subtle bugs

It can cause bugs, but there are probably not a lot of them in the wild.

and why such a thing is allowed as it is not intuitive as a reference?

To allow for binding references to prvalues to not have to copy them.

Take john's example in the comments:

void foo(const int& ri);

foo(3.14159);

In practice, there's little risk here. You call the function and in most scenarios, the value ri references is not expected to change during the call.

If you actually do have a situation where another function may change the referenced value, you can constrain your function to not allow for anything but the exact type you want to bind a reference to to avoid the temporary being created:

void foo(std::same_as<int> auto const& ri);

In reality, most compilers (MSVC with /W2 or higher and icx, clang and gcc with -Wfloat-conversion) are able to warn for this kind of mistake, further minimizing the risk for bugs.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.