Remix.run Logo
Joker_vD 11 hours ago

From what I can see in the codegen, defer is not implemented "properly": the deferred statements are only executed when the block exits normally; leaving the block via "return", "break", "continue" (including their labelled variants! those interact subtly with outer defers), or "goto" skips them entirely. Which, arguably, should not happen:

    var f = fopen("file.txt", "r");
    defer fclose(f);

    if fread(&ch, 1, 1, f) <= 0 { return -1; }
    return 0;
would not close file if it was empty. In fact, I am not sure how it works even for normal "return 0": it looks like the deferred statements are emitted after the "return", textually, so they only properly work in void-returning function and internal blocks.
ricardobeat 10 hours ago | parent [-]

Did you manage to compile this example?

Joker_vD 9 hours ago | parent [-]

Yes, actually:

    $ cat kekw.zc
    include <stdio.h>
    
    fn main() {
        var f = fopen("file.txt", "r");
        defer fclose(f);
    
        var ch: byte;
        if fread(&ch, 1, 1, f) <= 0 { return -1; }
        return 0;
    }
    $ ./zc --emit-c kekw.zc
    [zc] Compiling kekw.zc...
    $ tail -n 12 out.c
    int main()
    {
        {
        __auto_type f = fopen("file.txt", "r");
        uint8_t ch;
    if ((fread((&ch), 1, 1, f) <= 0))     {
        return (-1);
        }
        return 0;
    fclose(f);
        }
    }