3

I am trying to understand the differences of value categories and I found this document by Microsoft.

enter image description here

- An xvalue is a glvalue that [...]
- An lvalue is a glvalue that is not an xvalue.
- An rvalue is a prvalue or an xvalue.

Why is an xvalue a glvalue? Why didn't they say An xvalue is an glvalue or an rvalue? It seems to me that this phrasing was intentionally made to convey something, but I don't understand why

ShadowRanger
  • 108,619
  • 9
  • 124
  • 184
Daniel Stephens
  • 596
  • 4
  • 14
  • 39
  • @ShadowRanger That is not a duplicate, sorry – Daniel Stephens Nov 05 '19 at 01:18
  • 2
    This is [the same wording on cppreference](https://en.cppreference.com/w/cpp/language/value_category) for xvalue. – Raymond Chen Nov 05 '19 at 01:19
  • Good to know! Then the same question would apply there. I don't understand why they only mentioned gvalues in that sentence – Daniel Stephens Nov 05 '19 at 01:20
  • 1
    The basic categories are lvalue, xvalue, prvalue and those are mutually exclusive. The categories "glvalue" and "rvalue" are collective terms. Your suggested change would imply that all glvalues are xvalues (which is not true -- in fact all xvalues are glvalues but not vice versa) – M.M Nov 05 '19 at 01:21
  • Somehow agree. Their phrasing then also implies that xvalues are glvalues and therefore lvalues. So afaiu then it would be better `An xvalue is an glvalue that is not an lvalue, or an rvalue that is not an prvalue` to be more precise, correct? – HelloWorld Nov 05 '19 at 01:25
  • 1
    The diagram is trying to say that `glvalue = lvalue + xvalue` and `rvalue = xvalue + prvalue`. It is possible for something to be simultaneously a `glvalue`, `xvalue`, and `rvalue`. It may be misleading if you mistake the diagram to be a Venn diagram and conclude that that the lack of overlap between the `glvalue` and `rvalue` boxes means that they are mutually exclusive. – Raymond Chen Nov 05 '19 at 01:26
  • 1
    Its probably worded that way because the whole motivation behind creating xvalues was for move semantics. – Taekahn Nov 05 '19 at 01:29
  • @RaymondChen I would definitely accept that as an answer! Thanks! – Daniel Stephens Nov 05 '19 at 01:30
  • @Taekahn would make sense, true! – Daniel Stephens Nov 05 '19 at 01:30
  • an xvalue isn't a "glvalue OR an rvalue". an xvalue is a "glvalue AND an rvalue" – bolov Nov 05 '19 at 01:31
  • How does [this answer](https://stackoverflow.com/a/3601748/1505939) not answer your question? – M.M Nov 05 '19 at 01:34

2 Answers2

2

Why didn't they say An xvalue is an glvalue or an rvalue?

Because rvalue had not been defined yet and because rvalue would be defined in terms of xvalue. One has to be defined without relying on the other to avoid the definition from becoming circular.

Also because xvalue is both a glvalue and an rvalue.

Furthermore, xvalue is a glvalue that is not an lvalue. Even further, xvalue is an rvalue that is not a prvalue. Lastly, xvalue is an expression that is neither lvalue nor prvalue.

I don't understand why they only mentioned gvalues in that sentence

Only glvalue and prvalue had been defined. See earlier mention of avoiding circular definition.

What are xvalues in C++

Well, you've seen its definition. The standard has following non-normative note that gives further information:

[basic.lval]

[ Note: An expression is an xvalue if it is:

  • the result of calling a function, whether implicitly or explicitly, whose return type is an rvalue reference to object type ([expr.call]),
  • a cast to an rvalue reference to object type ([expr.type.conv], [expr.dynamic.cast], [expr.static.cast] [expr.reinterpret.cast], [expr.const.cast], [expr.cast]),
  • a subscripting operation with an xvalue array operand ([expr.sub]),
  • a class member access expression designating a non-static data member of non-reference type in which the object expression is an xvalue ([expr.ref]), or
  • a .* pointer-to-member expression in which the first operand is an xvalue and the second operand is a pointer to data member ([expr.mptr.oper]).
eerorika
  • 181,943
  • 10
  • 144
  • 256
1

The diagram may be misleading.

There are lvalues, xvalues and prvalues. They are exclusive and complete, i.e. every expression is exactly one of: lvalue, xvalue or prvalue.

lvalues and xvalues are called collectively glvalues
xvalues and prvalues are called collectively rvalues

So xvalues are both glvalues AND rvalues.

bolov
  • 58,757
  • 13
  • 108
  • 182
  • So you mean the following diagram is even more misleading? It states that an lvalue has an identity but not movable which means it can be an lvalue or an xvalue. https://docs.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/cpp-value-categories#the-complete-picture-of-value-categories – Daniel Stephens Nov 05 '19 at 02:54
  • 1
    @DanielStephens that diagram is very good. An lvalue has identity (is a glvalue) but is not movable (is not rvalue). I don't get where you go the conclusion "it can be an lvalue or an xvalue". – bolov Nov 05 '19 at 05:47
  • 1
    glvalues have identities. rvalues can be moved. An xvalue has identity and is movable (it's at the intersection between the two). – bolov Nov 05 '19 at 05:48