logoalt Hacker News

sparkieyesterday at 2:58 PM1 replyview on HN

Defer might be better than nothing, but it's still a poor solution. An obvious example of a better, structural solution is C#'s `using` blocks.

    using (var resource = acquire()) {

    } // implicit resource.Dispose();
While we don't have the same simplicity in C because we don't use this "disposable" pattern, we could still perhaps learn something from syntax and use a secondary block to have scoped defers. Something like:

    using (auto resource = acquire(); free(resource)) {

    } // free(resource) call inserted here.
That's no so different to how a `for` block works:

    for (auto it = 0; it < count; it++) {

    } // automatically inserts it++; it < count; and conditional branch after secondary block of for loop.
A trivial "hack" for this kind of scoped defer would be to just wrap a for loop in a macro:

    #define using(var, acquire, release) \
        auto var = (acquire); \
        for (bool var##_once = true; var##_once; var##_once = false, (release))

    using (foo, malloc(szfoo), free(foo)) {
        using (bar, malloc(szbar), free(bar)) {
            ...
        } // free(bar) gets called here.
    } // free(foo) gets called here.

Replies

usefulcatyesterday at 4:14 PM

That is a different approach, but I don't think you've demonstrated why it's better. Seems like that approach forces you to introduce a new scope for every resource, which might otherwise be unnecessary:

    using (var resource1 = acquire() {
        using (var resource2 = acquire()) {
            using (var resource3 = acquire()) {
                // use resources here..
            }
        }
    }
Compared to:

    var resource1 = acquire();
    defer { release(resource1); }
    var resource2 = acquire();
    defer { release(resource2); }
    var resource3 = acquire();
    defer { release(resource3); }
    // use resources here
Of course if you want the extra scopes (for whatever reason), you can still do that with defer, you're just not forced to.
show 1 reply