Live data from Hacker News

Lvalues, rvalues, glvalues, prvalues, xvalues, help (2018)

blog.knatten.org

11–20 of 94 posts

Re: Lvalues, rvalues, glvalues, prvalues, xvalues, help (2018)

#12

Excellent explanation. Too bad it's necessary. && and std::move are the biggest warts in C++ (that's saying a lot), representing the need for programmers to be constantly aware of the less-than-obvious ways that a compiler might put an expression in one category or another. It's the programmer helping the compiler, instead of the other way around as it should be. In general, if I need an rvalue and it's legal to conv…

> In general, if I need an rvalue and it's legal to convert the lvalue I have into an rvalue, the compiler should do it automatically.

This is already done in some places. Example:

    std::unique_ptr get_int() {
        auto p = std::make_unique(1);

        // `p` is an lvalue but treated as an rvalue in the return statement.
        // (This would not compile otherwise because `p` is not copyable.)
        return p;
    }

Re: Lvalues, rvalues, glvalues, prvalues, xvalues, help (2018)

#13

lvalues are locatable, they represent an object that occupies some identifiable location in memory (has address). rvalues do not and therefore cannot be addressed (with & or *) I think of lvalues as things on the stack and rvalues as things stored in registers https://eli.thegreenplace.net/2011/12/15/understanding-lvalu...

> rvalues do not and therefore cannot be addressed (with & or *)

Correction: prvalues cannot be addressed. There are also xvalues, which are both rvalues and lvalues i.e. they can be addressed but can also be moved from. In practice I think these are always lvalues that have been cast to an rvalue reference, usually using std::move().

Re: Lvalues, rvalues, glvalues, prvalues, xvalues, help (2018)

#14
post #4

lvalues are locatable, they represent an object that occupies some identifiable location in memory (has address). rvalues do not and therefore cannot be addressed (with & or *) I think of lvalues as things on the stack and rvalues as things stored in registers https://eli.thegreenplace.net/2011/12/15/understanding-lvalu...

The article starts by explaining lvalues and rvalues more precisely than that, and breaks them up into 3 additional value categories in modern C++ (the ones in the title). (Also, lvalues aren't tied to the stack: they can be anywhere in memory, like heap or static.)

how can you have an lvalue stored in the heap? isn't the lvalue itself a pointer in the stack? obviously I see how it can have static storage.

Re: Lvalues, rvalues, glvalues, prvalues, xvalues, help (2018)

#15
post #12

Excellent explanation. Too bad it's necessary. && and std::move are the biggest warts in C++ (that's saying a lot), representing the need for programmers to be constantly aware of the less-than-obvious ways that a compiler might put an expression in one category or another. It's the programmer helping the compiler, instead of the other way around as it should be. In general, if I need an rvalue and it's legal to conv…

> In general, if I need an rvalue and it's legal to convert the lvalue I have into an rvalue, the compiler should do it automatically. This is already done in some places. Example: std::unique_ptr get_int() { auto p = std::make_unique (1); // `p` is an lvalue but treated as an rvalue in the return statement. // (This would not compile otherwise because `p` is not copyable.) return p; }

That is the right approach IMO. What I'm basically saying is "more of this". It's clearly possible for C++ compilers to do this in many more cases. They already do most of the hard parts just to produce some of the error messages that they do. Why not use that knowledge more often to help the programmer instead of burdening them?

Re: Lvalues, rvalues, glvalues, prvalues, xvalues, help (2018)

#16
post #12

Excellent explanation. Too bad it's necessary. && and std::move are the biggest warts in C++ (that's saying a lot), representing the need for programmers to be constantly aware of the less-than-obvious ways that a compiler might put an expression in one category or another. It's the programmer helping the compiler, instead of the other way around as it should be. In general, if I need an rvalue and it's legal to conv…

> In general, if I need an rvalue and it's legal to convert the lvalue I have into an rvalue, the compiler should do it automatically. This is already done in some places. Example: std::unique_ptr get_int() { auto p = std::make_unique (1); // `p` is an lvalue but treated as an rvalue in the return statement. // (This would not compile otherwise because `p` is not copyable.) return p; }

Yes RVO is one case where the compiler will do it automatically.

I think copy initialization of an object will have the same will apply copy elision as well to result in the same performance, but I'm not entirely sure.

Re: Lvalues, rvalues, glvalues, prvalues, xvalues, help (2018)

#18

Excellent explanation. Too bad it's necessary. && and std::move are the biggest warts in C++ (that's saying a lot), representing the need for programmers to be constantly aware of the less-than-obvious ways that a compiler might put an expression in one category or another. It's the programmer helping the compiler, instead of the other way around as it should be. In general, if I need an rvalue and it's legal to conv…

It's not what what you're asking is unreasonable in concept, but that it goes against how RAII is used in C++; it'd make more sense in a new language. Specifically the issue is that despite its name, RAII isn't merely used for resource acquisition, but also to define dynamic scopes. That means destroying an object too early (which can happen if an object is automatically moved) can cause a subsequent statement that doesn't syntactically depend on the variable holding that object to see the wrong program state. So if your compiler moved objects automatically, that'd break code that uses RAII as a dynamic scoping mechanism.

That said though, it might be cool to have an [[attribute]] for classes (maybe [[automove]]? or [[resource]]? or [[functional]] or [[dataflow]]??) that lets you declare that that a class's construction and destruction (or maybe all members... ) can be assumed to have no side-effects for clients to depend on, or something like that... if they can work it out that'd be cool. Ideally it'd mean that an automatic variable of that type can be destroyed following its last dependency in any given scope.

Re: Lvalues, rvalues, glvalues, prvalues, xvalues, help (2018)

#19
post #4

Earlier quoted context omitted.

The article starts by explaining lvalues and rvalues more precisely than that, and breaks them up into 3 additional value categories in modern C++ (the ones in the title). (Also, lvalues aren't tied to the stack: they can be anywhere in memory, like heap or static.)

how can you have an lvalue stored in the heap? isn't the lvalue itself a pointer in the stack? obviously I see how it can have static storage.

If foo is an lvalue, then I believe (for example)

   *(foo[0].bar->baz)
is also an lvalue, and those pointer dereferences can go anywhere. Those values occupy a location in memory, as you said, even if it isn't on the stack.
Post reply on HN