Lvalues, rvalues, glvalues, prvalues, xvalues, help (2018)
41–50 of 94 posts
Re: Lvalues, rvalues, glvalues, prvalues, xvalues, help (2018)
#42Is 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…
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)
#43Earlier 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.
Re: Lvalues, rvalues, glvalues, prvalues, xvalues, help (2018)
#44Earlier 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.
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)
#45Earlier 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…
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)
#46Earlier 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.
Re: Lvalues, rvalues, glvalues, prvalues, xvalues, help (2018)
#47lvalues 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...
Re: Lvalues, rvalues, glvalues, prvalues, xvalues, help (2018)
#48Re: Lvalues, rvalues, glvalues, prvalues, xvalues, help (2018)
#49Earlier 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.
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)
#50Earlier 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…
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.