olist
olist

Reputation: 1039

address changes after a rvalue reference conversion

#include <iostream>
using namespace std;

int main()
{
  int i = 0;
  cout << &i << endl;

  const auto &ref = (short&&)i;
  cout << &ref << endl;

  return 0;
}

Why is &i different from &ref? (short&)i doesn't cause this problem. Does (short&&)i generate a temporary variable?

Upvotes: 2

Views: 101

Answers (4)

eerorika
eerorika

Reputation: 238401

It's because you're doing a different type of cast. The C style explicit conversion cast does always a static cast, if it could be interpreted as a static cast; otherwise it does a reinterpret cast. And/or const cast as needed.

(short&&)i is a static cast because it can be interpreted as static_cast<short&&>(i). It creates a temporary short object, to which ref is bound. Being a different object, it has a different address.

(short&)i is a reinterpret cast because it cannot be interpreted as static_cast<short&>(i) which is ill formed. It reinterprets the int reference as short reference, and ref is bound to the the same object. Note that accessing the object through this reference would have undefined behaviour.

Upvotes: 4

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385274

This creates a lvalue reference to a thing that exists:

const auto& ref = i;

The expressions &ref and &i will therefore give the same result.

This is also true of:

const auto& ref = (int&)i;

which is basically the same thing.

However, casting to something that is not a lvalue reference to T (so, to a value, or to an rvalue reference of another type!) must create a temporary; this temporary undergoes lifetime extension when bound to ref. But now ref does not "refer to" i, so the address-of results will differ.

It's actually a little more complicated than that, but you get the idea. Besides, don't write code like this! An int is not a short and you can't pretend that it is.

Upvotes: 3

Constantinos Glynos
Constantinos Glynos

Reputation: 3186

Apparently it creates a temporary.

Actually the compiler will tell you itself. Try this:

auto &ref = (short&&)i;
cout << &ref << endl;

The error says:

error: non-const lvalue reference to type 'short' cannot bind to a temporary of type 'short'

Test code here.

Upvotes: 2

Jarod42
Jarod42

Reputation: 217810

(short&&)i creates a temporary, so you take address of an other object, so address might differ.

Upvotes: 1

Related Questions