Live data from Hacker News

Rusty.hpp: A Borrow Checker and Memory Ownership System for C++20

github.com

61–70 of 174 posts

Re: Rusty.hpp: A Borrow Checker and Memory Ownership System for C++20

#61
Can someone familiar with both please explain the benefit of Rust's borrow checker memory management model over C++'s std::unique_ptr and shared_ptr ? Is there some safety argument to prefer Rust's model, or is it something else ?

I'm not aware of any C++ compiler doing it, but it seems smart pointer overhead could be automatically and safely reduced (in same way one can do it manually) by the compiler lowering the generated code to use raw pointers where permissible.

Re: Rusty.hpp: A Borrow Checker and Memory Ownership System for C++20

#62
post #47

Earlier quoted context omitted.

The people criticizing std::optional are doing a very poor job. Here's the big issue: unchecked access to std::optional with operator* has undefined behavior when there's no value. This is unforgivably bad design since you can enforce exhaustive checking at compile time, but C++ isn't going in that direction. std::optional offers value() for checked access too, but that checks at runtime and throws an exception. It i…

can you show me how rust does this? I'm genuinely curious. I've made a toy example to show how c++ checks for undefined behavior at compile time, I am unaware of rust being able to do the same without runtime costs (however small they may be, this is a toy example after all) https://godbolt.org/z/cT9bqz8z7

Compile time checked pattern matching: https://doc.rust-lang.org/book/ch18-03-pattern-syntax.html

Re: Rusty.hpp: A Borrow Checker and Memory Ownership System for C++20

#63

Can someone familiar with both please explain the benefit of Rust's borrow checker memory management model over C++'s std::unique_ptr and shared_ptr ? Is there some safety argument to prefer Rust's model, or is it something else ? I'm not aware of any C++ compiler doing it, but it seems smart pointer overhead could be automatically and safely reduced (in same way one can do it manually) by the compiler lowering the g…

> it seems smart pointer overhead could be automatically and safely reduced (in same way one can do it manually) by the compiler lowering the generated code to use raw pointers where permissible.

The sheer difficulty of doing this is one of the motivations behind Rust's borrow checker, which uses a combination of type system and static analyses to prove the safety without running anything. In fact this problem is probably easier to solve for languages where everything is GC-managed; those languages would have a heavy runtime which can transparently handle that in principle!

Re: Rusty.hpp: A Borrow Checker and Memory Ownership System for C++20

#64

Can someone familiar with both please explain the benefit of Rust's borrow checker memory management model over C++'s std::unique_ptr and shared_ptr ? Is there some safety argument to prefer Rust's model, or is it something else ? I'm not aware of any C++ compiler doing it, but it seems smart pointer overhead could be automatically and safely reduced (in same way one can do it manually) by the compiler lowering the g…

Rust has unique and shared pointers too (Box and Arc/Rc). But using them when unnecessary results in extra heap allocations. I’m not aware of C++ compiler that can consistently rewrite uses of unique_ptr to heap-allocated objects to use raw pointers to stack-allocated objects instead.

Re: Rusty.hpp: A Borrow Checker and Memory Ownership System for C++20

#65

Can someone familiar with both please explain the benefit of Rust's borrow checker memory management model over C++'s std::unique_ptr and shared_ptr ? Is there some safety argument to prefer Rust's model, or is it something else ? I'm not aware of any C++ compiler doing it, but it seems smart pointer overhead could be automatically and safely reduced (in same way one can do it manually) by the compiler lowering the g…

Read this: https://alexgaynor.net/2019/apr/21/modern-c++-wont-save-us/

It will help you understand why "smart pointers" still won't help you.

Re: Rusty.hpp: A Borrow Checker and Memory Ownership System for C++20

#66

Can someone familiar with both please explain the benefit of Rust's borrow checker memory management model over C++'s std::unique_ptr and shared_ptr ? Is there some safety argument to prefer Rust's model, or is it something else ? I'm not aware of any C++ compiler doing it, but it seems smart pointer overhead could be automatically and safely reduced (in same way one can do it manually) by the compiler lowering the g…

Rust has unique and shared pointers too (Box and Arc/Rc). But using them when unnecessary results in extra heap allocations. I’m not aware of C++ compiler that can consistently rewrite uses of unique_ptr to heap-allocated objects to use raw pointers to stack-allocated objects instead.

Theres nothing special about unique_ptr, if you dont want allocations and youre ok with just moving your values around directly, you use value and move semantics.

Re: Rusty.hpp: A Borrow Checker and Memory Ownership System for C++20

#67

Can someone familiar with both please explain the benefit of Rust's borrow checker memory management model over C++'s std::unique_ptr and shared_ptr ? Is there some safety argument to prefer Rust's model, or is it something else ? I'm not aware of any C++ compiler doing it, but it seems smart pointer overhead could be automatically and safely reduced (in same way one can do it manually) by the compiler lowering the g…

The point is that it keeps track of multiple references and disallows mutable and immutable references at the same time across threads, for example, and disallows multiple mutable references altogether.

The rust borrow checker works on values, and all that, not just on objects with RAII.

Re: Rusty.hpp: A Borrow Checker and Memory Ownership System for C++20

#68

Can someone familiar with both please explain the benefit of Rust's borrow checker memory management model over C++'s std::unique_ptr and shared_ptr ? Is there some safety argument to prefer Rust's model, or is it something else ? I'm not aware of any C++ compiler doing it, but it seems smart pointer overhead could be automatically and safely reduced (in same way one can do it manually) by the compiler lowering the g…

Generally in C++ this kind of data transformation faces a lot of barriers. For example, the language semantics require struct fields to have the unoptimized memory layout and contents as far as the user can observe at the byte level.

Low-level programming would be quite a different scene if there were a lot of permitted data optimizations by compilers (profile guided more concise representations of structs, replacing pointer based data structures with indexed layouts, etc).

Re: Rusty.hpp: A Borrow Checker and Memory Ownership System for C++20

#69
post #37

Earlier quoted context omitted.

> The practical use of optional is that you know where T is going to be constructed and can reason about the memory layout. The practical use for me is making interfaces safer. Where I saw colleagues use pointers as optionals, end up mis-tracking what can be null and what can't, only checking it inconsistently, and triggering UB, I now have a clear distinction between optional and non-optional arguments/returns with…

> Most of the time, I want to pass/return a reference Surprised to hear that you want to return a reference so frequently.

It's not really my choice, I'm working in a big codebase I didn't write. Lots of large classes containing large collections with getters and setters.

Re: Rusty.hpp: A Borrow Checker and Memory Ownership System for C++20

#70
post #38

Earlier quoted context omitted.

The Option type seems to have various standard Rust methods like expect() implemented that I don't believe std::optional has. I haven't checked recent C++ standards, but I don't believe you can use partial classes/extensions in C++ like some other OO languages to add these methods to a native type. Many helper functions commonly used in Rust also only seem to exist in C++23, which not ever project can be compiled und…

> The Option type seems to have various standard Rust methods like expect() Isn't that value()?

.expect() also takes a message that it prints when the value is empty.

Unlike C++, Rust doesn't support throwing exceptions, so expect() failing would panic. By default, this means dumping a stack trace and terminating the program, and the message provided in "expect" would be printed right before the stack trace.

For example:

    fn main() {
        let x: Option = None;
        x.expect("Oh no!");
    }

will print:

    thread 'main' panicked at src/main.rs:3:7:
    Oh no!
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
With RUST_BACKTRACE set to "full", it'll print:

    $ RUST_BACKTRACE=full ./target/release/demo
    thread 'main' panicked at src/main.rs:3:7:
    Oh no!
    stack backtrace:
       0:     0x5ff43befa755 - ::fmt::ha52e99bffe3c0898
       1:     0x5ff43bf1769b - core::fmt::write::h5fdd5156f2480a24
       2:     0x5ff43bef8a5f - std::io::Write::write_fmt::ha2c0b019f448d2c3
       3:     0x5ff43befa52e - std::sys_common::backtrace::print::he84813a4ed1c2825
       4:     0x5ff43befb7e9 - std::panicking::default_hook::{{closure}}::h033521c27c9929b1
       5:     0x5ff43befb52d - std::panicking::default_hook::had42987aad9de78c
       6:     0x5ff43befbc83 - std::panicking::rust_panic_with_hook::h80fc1b429f5a5699
       7:     0x5ff43befbb64 - std::panicking::begin_panic_handler::{{closure}}::h5aa7b89233b1ae33
       8:     0x5ff43befac19 - std::sys_common::backtrace::__rust_end_short_backtrace::h0e4c5e6cee7f8a24
       9:     0x5ff43befb897 - rust_begin_unwind
      10:     0x5ff43bee0b63 - core::panicking::panic_fmt::h3bea7be9b6a41ace
      11:     0x5ff43bf16c6c - core::panicking::panic_display::h20da06138ce63f85
      12:     0x5ff43bee0b2c - core::option::expect_failed::h92448d4f1092eaaa
      13:     0x5ff43bee127a - demo::main::ha244b8f1ce6eaa44
      14:     0x5ff43bee1223 -     std::sys_common::backtrace::__rust_begin_short_backtrace::hfc5c93265480da58
      15:     0x5ff43bee1239 - std::rt::lang_start::{{closure}}::h988fdfb65ef3da3b
      16:     0x5ff43bef6be6 - std::rt::lang_start_internal::h64c4082ce77a6bd6
      17:     0x5ff43bee12a5 - main
      18:     0x741d2a628150 - __libc_start_call_main
                               at ./csu/../sysdeps/nptl/libc_start_call_main.h:    58:16
      19:     0x741d2a628209 - __libc_start_main_impl
                                   at ./csu/../csu/libc-start.c:360:3
      20:     0x5ff43bee1155 - _start
      21:                0x0 - 
Whether you would want to replicate this behaviour in C++, I don't know; I find panic!() to be quite destructive, and catastrophic when it's used in libraries or frameworks. I think the C++ implementation just throws an exception, but Rust's .expect() does not behave like .value() in C++.
Post reply on HN