15

C++11 introduced new value categories, one of them is xvalue.

It is explained by Stroustrup as something like (im category): "it is a value, which has identity, but can be moved from".

Another source, cppreference explains:

a glvalue is an expression whose evaluation determines the identity of an object, bit-field, or function;

And xvalue is a glvalue, so this is statement is true for xvalue too.

Now, I thought that if an xvalue has identity, then I can check if two xvalues refer to the same object, so I take the address of an xvalue. As it turned out, it is not allowed:

int main() {
    int a;
    int *b = &std::move(a); // NOT ALLOWED
}

What does it mean that xvalue has identity?

geza
  • 28,403
  • 6
  • 61
  • 135

1 Answers1

7

The xvalue does have an identity, but there's a separate rule in the language that a unary &-expression requires an lvalue operand. From [expr.unary.op]:

The result of the unary & operator is a pointer to its operand. The operand shall be an lvalue [...]

You can look at the identity of an xvalue after performing rvalue-to-lvalue conversion by binding the xvalue to a reference:

int &&r = std::move(a);
int *p = &r;  // OK
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • 3
    Yes, but you can do the "same" to a prvalue, if you assign it to `const &`. And a prvalue doesn't have an identity. – geza Jun 10 '18 at 12:32
  • 1
    @geza: In C++17, you would say that the prvalue is materialized (= converted to a glvalue) when it's bound to a reference. Prior to C++17, binding to a reference s just a general rvalue-to-lvalue conversion, which does indeed *create* a glvalue if a prvalue is given. But in the OP's example there is no prvalue, so the identity we're talking about is always unambiguously the same. ("No materialization happens", in C++17-terms.) – Kerrek SB Jun 10 '18 at 12:50
  • Another thing to consider is that `std::move` converts any value to a glvalue, but if the original value was already a glvalue, then its glvalueness is unchanged (only "l" is changed to "x"). – Kerrek SB Jun 10 '18 at 12:53
  • @geza: A bit like this: https://sketch.io/render/sk-7b28f85a9409d8a5a0afc955c9b7f667.jpeg – Kerrek SB Jun 10 '18 at 13:00
  • 1
    So basically you say, that because xvalue has identity, it doesn't need materialization (because it is already materialized), while a prvalue needs it in certain situations? That's the main difference between a "has identity" an a "doesn't have identity" variable? – geza Jun 10 '18 at 13:29
  • 1
    @geza: Kind of -- but not "variable", but rather "value". A variable can never be a prvalue. Either a variable is an object, or it's a reference, and once a value binds to a reference, it must become a glvalue. – Kerrek SB Jun 11 '18 at 19:53