Live data from Hacker News

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

blog.knatten.org

41–50 of 94 posts

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

#42
post #9
post #6

Is it totally exactly true that a `glvalue` is either an `xvalue` or a `lvalue` and nothing else? Similarly, is a `rvalue` either a `xvalue` or a `prvalue`?

Yes, section 8.2.1 "Value Category" (page 80) of the C++17 standard[0] defines the terms as: (1.1) - A glvalue is an expression whose evaluation determines the identity of an object, bit-field, or function. (1.2) - A prvalue is an expression whose evaluation initializes an object or a bit-field, or computes the value of the operand of an operator, as specified by the context in which it appears. (1.3) - An xvalue is…

Thanks, I actually recall seeing that diagram.

I agree that the article is clearer. Because I didn't get it when I saw that diagram, but I do get it after reading the article.

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

#43
post #36

Earlier quoted context omitted.

FWIW I mostly use “out params” as in C because I think moves incur a lot of complexity, as well explained in this article. It’s also more lines of code to write. Some people may quibble with it but I think it’s still a fine style of writing C++, and in fact most C++ you’ll see is written like that, since this is a new-ish feature.

Agreed. RVO is not guaranteed, and move is complex. Smart pointers have overhead. Out params are for the most part a sensible choice in C++. Sadly. I'm honestly shocked that this problem hasn't been addressed in a better way.

RVO is guaranteed in C++17

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

#44
post #36

Earlier quoted context omitted.

FWIW I mostly use “out params” as in C because I think moves incur a lot of complexity, as well explained in this article. It’s also more lines of code to write. Some people may quibble with it but I think it’s still a fine style of writing C++, and in fact most C++ you’ll see is written like that, since this is a new-ish feature.

Agreed. RVO is not guaranteed, and move is complex. Smart pointers have overhead. Out params are for the most part a sensible choice in C++. Sadly. I'm honestly shocked that this problem hasn't been addressed in a better way.

Out-parameters are a terrible choice in C++. If it matters whether RVO is guaranteed, you are probably making something more complicated than it needs to be.

Value semantics give you sensible behavior. Smart pointers should not appear in user-visible interfaces.

It is easy to tie yourself in knots by doing the complicated thing. The solution is to do the simple thing.

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

#45

Earlier quoted context omitted.

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 d…

> it goes against how RAII is used in C++ That's an excellent point. To be honest, I think it's a problem with how RAII is used, conflating execution scope and object lifetime in a way that makes "move" a bit of a mess. That's why I prefer explicit "defer" like some languages have. Nonetheless, it's a common and useful enough idiom that breaking it is not something to be taken lightly. Maybe it's not really a solvabl…

> I think it's a problem with how RAII is used, conflating execution scope and object lifetime in a way that makes "move" a bit of a mess.

It seems to me that there's a subset that is just fine. Use RIAA to, for example, take a lock and automatically release it when you leave a scope. That's not a problem, in itself. And go ahead and use move semantics, too. That's also fine.

But don't use move on an object that's doing RIAA to take and release a lock. That, in my view, is not much of a restriction, because if you think about it, that's not really a reasonable thing to want to do. That RIAA lock-taker is not the kind of object that you want to move, or even copy. Explicitly disable those actions (private copy constructor and operator, private move), and you should be good.

Or have I missed something?

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

#46

Earlier quoted context omitted.

Your proposed better pattern to follow when one needs a finally block in C++ is...?

I already mentioned "defer" as in Go or Zig. It's explicitly tied to scope exit, not object lifetime, so it avoids all of the problems inherent in confusing the two.

I didn't ask what language you would use. I asked what you would do in C++, given you're criticizing people for writing such code in the language. If you're put so much thought into this problem like you claim then surely you must have a better alternative in mind.

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

#47

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...

I used to think that. It's simple, right? Then i said so on the C++ Slack and got the hell beaten out of me. In modern C++, lvalue and rvalue simply don't mean what they do in other languages. Wild but true.

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

#49

Earlier quoted context omitted.

I already mentioned "defer" as in Go or Zig. It's explicitly tied to scope exit, not object lifetime, so it avoids all of the problems inherent in confusing the two.

I didn't ask what language you would use. I asked what you would do in C++, given you're criticizing people for writing such code in the language. If you're put so much thought into this problem like you claim then surely you must have a better alternative in mind.

I don't care what people "would do" in C++ today, because my whole point is that C++ started down this bad path years ago. I'm not criticizing people for writing such code. I'm criticizing the standards-makers who made such hacks (seem) necessary. It's not about having put thought into it either. Lots of people had put plenty of thought into it when the various versions of C++ were standardized. This is about making the right choices from among the alternatives available, and that was not done.

Demanding a solution that is both applicable to C++ as it exists today and yet not in C++ today is demanding two contradictory things. It's demanding that the same thing both did and didn't happen. It's dishonest. You want a suggestion? Adopt "defer" for the next version of C++. It's the best we can do. We can't change the past, but we can learn from it if we don't get stuck trying to excuse past mistakes and attack those who point them out.

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

#50

Earlier quoted context omitted.

> it goes against how RAII is used in C++ That's an excellent point. To be honest, I think it's a problem with how RAII is used, conflating execution scope and object lifetime in a way that makes "move" a bit of a mess. That's why I prefer explicit "defer" like some languages have. Nonetheless, it's a common and useful enough idiom that breaking it is not something to be taken lightly. Maybe it's not really a solvabl…

> I think it's a problem with how RAII is used, conflating execution scope and object lifetime in a way that makes "move" a bit of a mess. It seems to me that there's a subset that is just fine. Use RIAA to, for example, take a lock and automatically release it when you leave a scope. That's not a problem, in itself. And go ahead and use move semantics, too. That's also fine. But don't use move on an object that's do…

> don't use move on an object that's doing RIAA to take and release a lock.

Absolutely. If the question is "what would I do in C++ today" then my answer is that I would use RAII subject to common-sense rules like this.

> Explicitly disable those actions (private copy constructor and operator, private move)

That's a decent enough solution within the context of C++ as an unchangeable thing, but I want people to look beyond that context. C++ has never been an unchangeable thing. Programmers shouldn't have to take such extra steps, so closely tied to how the language works that year, to get a conceptually simple result. That's how bugs creep in, and how even correct code becomes drudgery. We have no choice but to accept it now, but we shouldn't accept it permanently.

Post reply on HN