News for hackers. Stuff that matters.
Re:Sayonara, C++, and Hello to Rust by AndyKelley on Friday December 10, 2021 @12:45AM (#29506814)
RAII works fine in Zig
Re:Sayonara, C++, and Hello to Rust by lenkite on Friday December 10, 2021 @04:11AM (#29507959)
Re:Sayonara, C++, and Hello to Rust by AndyKelley on Friday December 10, 2021 @04:17AM (#29507992)
show me a raii code example in C++ and I'll show you the zig equivalent
Re:Sayonara, C++, and Hello to Rust by lenkite on Friday December 10, 2021 @10:41AM (#29511169)
Note that in `good` below, one can have many such lock guards: lk1, lk2, etc without any explicit lock release expression in the body of the function.

    std::mutex m;
    void good()
    {
    std::lock_guard<std::mutex> lk(m); // RAII class: mutex acquisition is initialization
    f();                               // if f() throws an exception, the mutex is released
    if(!everything_ok()) return;       // early return, the mutex is released
    }                                      // if good() returns normally, the mutex is released
Re:Sayonara, C++, and Hello to Rust by AndyKelley on Friday December 10, 2021 @06:16PM (#29516648)

    var m: std.Thread.Mutex = .{};

    fn good() !void {
        m.lock();
        defer m.unlock();

        try f();
        if (!everything_ok()) return;
    }
It's still the RAII pattern. The explicit call to deinitialization does not disqualify it. I can overcomplicate it with a LockGuard class too:

    const LockGuard = struct {
        mutex: *std.Thread.Mutex,

        fn init(mutex: *std.Thread.Mutex) !LockGuard {
            mutex.lock();
            return .{
                .mutex = mutex,
            };
        }

        fn deinit(lg: *LockGuard) void {
            lg.mutex.unlock();
        }
    };

    fn good() !void {
        var lk = try LockGuard.init(&m);
        defer lk.deinit();

        try f();
        if (!everything_ok()) return;
    }
In this case it demonstrates an improvement over C++, which is what happens if an error happens during a constructor. In C++ throwing an exception in a constructor is essentially UB; in zig it's a regular function call just like anything else.
Re:Sayonara, C++, and Hello to Rust by lenkite on Sunday December 12, 2021 @01:42PM (#29532305)
Thanks for the informative snippet, but explicit expressions involving defer is not what RAII means. In RAII resource is automatically tied to object lifetime.

https://en.wikipedia.org/wiki/Resource_acquisition_is_initia...

Regarding errors in a C++ constructor: https://isocpp.org/wiki/faq/exceptions#ctors-can-throw