File: lvalues.yo

package info (click to toggle)
c%2B%2B-annotations 10.6.0-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 10,536 kB
  • ctags: 3,247
  • sloc: cpp: 19,157; makefile: 1,521; ansic: 165; sh: 128; perl: 90
file content (98 lines) | stat: -rw-r--r-- 4,241 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
Although this section contains forward references to chapters ref(String),
ref(Classes), and ref(PointMembers), its topic best fits the current
chapter. This section can be skipped without loss of continuity, and you might
consider returning to it once you're familiar with the contents of these
future chapters.

Historically, the bf(C) programming language distinguished between
em(lvalues) and em(rvalues). The terminology was based on
assignment expressions, where the value to the left of the assignment operator
receives a value (e.g., it referred to a location in memory where a value
could be written into, like a variable), while the value to the right of the
assignment operator only had to represent a value (it could be a temporary
variable, a constant value or the value stored in a variable):
        verb(
    lvalue = rvalue;
        )

bf(C++) adds to this basic distinction several new ways of referring to
values: 
    itemization(
    itt(lvalue): an emi(lvalue) in bf(C++) has the same meaning as in
        bf(C). It refers to a location where a value can be stored, like a
        variable, a reference to a variable, or a dereferenced pointer.
    itt(xvalue): an emi(xvalue) indicates an emi(expiring value). An expiring
        value refers to an em(object) (cf. chapter ref(Classes)) just before
        its lifetime ends. Such objects normally have to make sure that
        resources they own (like dynamically allocated memory) also cease to
        exist, but such resources may, just before the object's lifetime ends,
        be moved to another location, thus preventing their destruction.
    itt(gvalue): a emi(gvalue) is a emi(generalized lvalue). A generalized
        lvalue refers to anything that may receive a value. It is either an
        lvalue or an xvalue.
    itt(prvalue): a emi(prvalue) is a emi(pure rvalue): a literal value (like
        tt(1.2e3)) or an immutable object (e.g., the value returned from a
        function returning a constant tt(std::string) (cf. chapter
        ref(String)))
    )

An expression's value is an xvalue if it is:
    itemization(
    it() the value returned by a function returning an rvalue reference to an
            object;
    it() an object that is cast to an rvalue reference;
    it() an expression accessing a non-static class data member whose object
            is 
        itemization(
        it() an xvalue, or
        it() a tt(.*) (pointer-to-member) expression (cf. chapter
            ref(PointMembers)) in which the left-hand side operand is an
            xvalue and the right-hand side operand is a pointer to a data
            member.
        )
        The effect of this rule is that named rvalue references are treated as
            lvalues and anonymous rvalue references to objects are treated as
            xvalues.nl()
        Rvalue references to functions are treated as lvalues whether
            anonymous or not.
    )

Here is a small example. Consider this simple struct:
        verb(
    struct Demo 
    {
        int d_value;
    };
        )
    In addition we have these function declarations and definitions:
    verb(
    Demo &&operator+(Demo const &lhs, Demo const &rhs);
    Demo &&factory();

    Demo demo;
    Demo &&rref = static_cast<Demo &&>(demo);
    )

    Expressions like
        verb(
    factory();
    factory().d_value;
    static_cast<Demo &&>(demo);
    demo + demo
        )
    are xvalues. However, the expression
        verb(
    rref;
        )
    is an lvalue.

In many situations it's not particularly important to know what kind of gvalue
or what kind of rvalue is actually used. In the annotations() the term
emi(lhs) (i(left hand side)) is frequently used to indicate an operand that's
written to the left of a binary operator, while the term emi(rhs) 
    (i(right hand side)) is frequently used to indicate an operand that's
written to the right of a binary operator. Lhs and rhs operands could actually
be gvalues (e.g., when representing ordinary variables), but they could also
be prvalues (e.g., numeric values added together using the addition
operator). Whether or not lhs and rhs operands are glvalues can always be
determined from the context in which they are used.