Live data from Hacker News

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

blog.knatten.org

51–60 of 94 posts

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

#51

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…

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

It actually is (at least re: moving). Tying lock acquisition to object lifetime is a Good Thing (TM), and if you wanted to extend or shrink the lifetime of that lock you should be able to do that by moving the RAII object, the same as how you could do it with a shared_ptr or whatever.

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

#52
post #40

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…

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.

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

Are you seriously suggesting that C++ with defer is a new language? Unlike, say, C++ with lambdas? That's just silly.

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

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

C++ is for sure extremely complicated, but I’d argue that a full understanding of value categories (glvalues, xrvalues, etc) isn’t necessary to be productive with the language.

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

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

I spent five years in the C++ mines, and spooky corners and edge cases and arcane rules like this made me happy to leave.

Working in a language where I can be concerned with the task and hand and not ownership issues is refreshing.

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

#55
post #44

Earlier quoted context omitted.

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.

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

Good advice. Corollary: don't use tools that make it hard to do simple things, or force you to live with the not-simple things others have done.

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

#56
post #12

Earlier quoted context omitted.

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

Because the compiler can't always know when moving a value is acceptable.

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

#58
post #40

Earlier quoted context omitted.

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.

> It would make sense ONLY if you want to have a new language. Are you seriously suggesting that C++ with defer is a new language? Unlike, say, C++ with lambdas? That's just silly.

C++ without deterministic destructors to manage lifetime would be a (fundamentally) different language.

Furthermore, also disagree with you that it would be a better language. C++ has many warts but object lifetime and RAII is amongst its strong suits (unarguably, I thought — yes, resource lifetime is complex, but it’s inherently so; C++ just makes the complexity explicit and handles it in a good way). Handling resource lifetime in languages with nondeterministic GCs can be such a pain that it has fundamental, detrimental impact on the architecture. Just look at .NET’s handling of `Dispose`. I’ve written a ton of .NET GUI code, and handling resource lifetime (in particular GDI+) is an absolute pain point, which is uniquely caused by the lack of deterministic object lifetime.

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

#60
post #30

Earlier quoted context omitted.

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

Exception is also a result of supporting recoverable allocation/construction failures, IMO. When you need to support a failable Vec::new, what will be the type of its Error? There are two choices in this case:

a) wrap underlying errors into something like VecNewError, which is tedious due to the prevalence of errors if every construction/allocation can fail, kindly similar to the CheckedException dilemma

b) type erasing it by Box it or dyn Error, and use ? operator to transparently pass errors to upper level, in which case the user need to downcast with match to extract information needed, and exception is essentially the syntax sugar for this case because exception acts like a ? operator after all failable function calls

a) is usually used in a language where errors are rare, and b) is preferred when the errors are common.

Post reply on HN