Live data from Hacker News

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

blog.knatten.org

31–40 of 94 posts

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

#31
post #30
post #26

Earlier quoted context omitted.

Also, Rust does not have copy or move constructors/operators; every copy or move is a pure memcpy() (there's Clone for when you need it, but clone is always an explicit call). This simplifies the model a lot.

C++'s move constructor can throw exceptions. An example would be moving a linked list, and the allocation of dummy tail node can fail. In my opinion, the design choice to support recoverable allocation failure in C++ reasons for most other designs.

You can make allocation failure recoverable in different ways. For example, Rust’s (yet to be stabilized) allocator API returns a Result: https://doc.rust-lang.org/stable/std/alloc/trait.Alloc.html#...

It is true that choosing to make this recoverable is a big part of it; in Rust we decided to make standard library data structures treat allocation as unrecoverable, and this does simplify the API of using them significantly. However, I would argue that the complexity in C++ comes more from using exceptions for this purpose than from that choice. Rust’s panics being used for unrecoverable errors only helps simplify the overall model. In other words, the ease of use goes unrecoverable > recoverable through result > recoverable through exceptions, and the model complexity comes from the choice of using exceptions over return values. We do have a plan for introducing a way to make the data structures recoverable, but it’s waiting on several things.

This is, of course, only my opinion.

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

#32

Earlier quoted context omitted.

> Because it'd break code. Then that's an indictment of the decisions that led to such code being written in the first place.

Only if you're quick to judge without understanding why such code is and will continue to be written.

You're pretty quick to assume I don't. Believe me, I understand. I just don't agree that it's a good idea to mix up object lifetimes and execution context by using destructors to "magically" release locks etc. It never was. The mistakes were made years ago.

I'm not quick to judge (in this case). I'm judging after careful consideration, because I know the difference between good and bad patterns. The ones being hasty are those who mistake their own comfort level with something (often because they know nothing else) for actual merit.

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

#33
post #19

Earlier quoted context omitted.

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.

oh okay, understood. frankly I don't have an airtight understanding of the c++ standards and I would have considered your expression to be a dereference operation on an lvalue, but not an lvalue itself. ty for the explanation!

They are not mutually exclusive. When a pointer has been set to point to an lvalue, dereferencing it yields that lvalue.

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

#34

Earlier quoted context omitted.

oh okay, understood. frankly I don't have an airtight understanding of the c++ standards and I would have considered your expression to be a dereference operation on an lvalue, but not an lvalue itself. ty for the explanation!

I'm sure there are some complex exceptions, but as a starter, you can think of lvalues as "anything you can assign to" (the l basically stands for left, as in, "can appear on the left of an assignment"). So, if you have something like `foo(val) = 10`, then `foo(val)` is an lvalue.

One of the complications is that if you take an l-value and const-qualify it, it is still an l-value (but not a modifiable l-value.)

https://www.geeksforgeeks.org/lvalue-and-rvalue-in-c-languag...

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

#35

Earlier quoted context omitted.

Only if you're quick to judge without understanding why such code is and will continue to be written.

You're pretty quick to assume I don't. Believe me, I understand . I just don't agree that it's a good idea to mix up object lifetimes and execution context by using destructors to "magically" release locks etc. It never was. The mistakes were made years ago. I'm not quick to judge (in this case). I'm judging after careful consideration, because I know the difference between good and bad patterns. The ones being hasty…

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

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

#36
post #11

Articles like this make me feel very smug about my decision never to go down the rabbithole of learning C++. I feel perfectly comfortable with using pointers (and my intuition about them) in C.

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.

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

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

global variables are lvalues, for instance.

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

#38

Earlier quoted context omitted.

You're pretty quick to assume I don't. Believe me, I understand . I just don't agree that it's a good idea to mix up object lifetimes and execution context by using destructors to "magically" release locks etc. It never was. The mistakes were made years ago. I'm not quick to judge (in this case). I'm judging after careful consideration, because I know the difference between good and bad patterns. The ones being hasty…

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)

#39
post #36
post #11

Articles like this make me feel very smug about my decision never to go down the rabbithole of learning C++. I feel perfectly comfortable with using pointers (and my intuition about them) in C.

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)

#40

Earlier quoted context omitted.

Only if you're quick to judge without understanding why such code is and will continue to be written.

You're pretty quick to assume I don't. Believe me, I understand . I just don't agree that it's a good idea to mix up object lifetimes and execution context by using destructors to "magically" release locks etc. It never was. The mistakes were made years ago. I'm not quick to judge (in this case). I'm judging after careful consideration, because I know the difference between good and bad patterns. The ones being hasty…

RAII is one of the core language feature of C++.

Replacing it with defer or GC will surely break existing programs.

It would make sense ONLY if you want to have a new language.

Post reply on HN