Allow multiple container-level `const _` declarations

Since Zig doesn’t have multi-line comments, the most obvious way to me to comment out multiple container-level declarations and/or fields is to wrap them in a struct with an omitted name:

const _ = struct {
    var commented_out_var: i32 = 42;
    pub fn commentedOutFunction() void {}
};

However, if I put multiple such ‘comments’ into one file, Zig starts complaining about duplicating names:

// main.zig

const _ = struct {
    var commented_out_var: i32 = 42;
};

pub fn main() void {}

const _ = struct {
    pub fn commentedOutFunction() void {}
};
$ zig run main.zig 
main.zig:1:7: error: duplicate struct member name '_'
const _ = struct {
      ^
main.zig:7:7: note: duplicate name here
const _ = struct {
      ^
main.zig:1:1: note: struct declared here
const _ = struct {
^~~~~

Could we fix the compiler and allow this? Of course I could give those structs some dummy names, like comment_var and comment_fn, but it obscures the intention, and also makes tools like zigimports report those identifiers as unused.

Or perhaps any other suggestions of quick ways of commenting out multiple lines in ‘spartan’ text editors? (like e.g. mousepad that I sometimes use).

Can you not put them in an if (false) block? Haven’t tried that myself but it seems plausible.
Maybe _ = struct { ... } could also work?

Looks like a problem that can be solved by mashing your head against the keyboard:

_gearfuishn” is the random string I got; your own results may vary :wink:

any other ways

This one seems to work! :

comptime {
    _ = struct {
        var commented_out_var: i32 = 42;
    };
}

pub fn main() void {}

comptime {
    _ = struct {
        pub fn commentedOutFunction() void {}
    };
}

Albeit with too much boilerplate per a comment. :slight_smile:

Oh, and this ugliness does work too:

usingnamespace struct {
    const _ = struct {
        var commented_out_var: i32 = 42;
    };
};

pub fn main() void {}

usingnamespace struct {
    const _ = struct {
        pub fn commentedOutFunction() void {}
    };
};

I didn’t believe it would, since it’s similar to the very first one. But somehow the name conflict is gone.

Anyway, don’t you guys think this inconsistency in treatment of _ identifiers should be fixed? By allowing the subj.

I think programmers shouldn’t use editors that can’t comment out multiple lines.

If @Xion’s solution doesn’t work for you, think about throwing away those editors and get one that supports at least the basics.

I believe with Change meaning of underscore from actual identifier name to ignoring the value being named · Issue #4164 · ziglang/zig · GitHub implemented you could use:

without getting a duplicate name error for _ and it is an accepted proposal.

2 Likes

Oh, nice. Glad to hear it’ll be amended eventually.

Use comptime blocks + discards + if (false):

// main.zig

comptime {
    _ = if (false) struct {
        var commented_out_var: i32 = 42;
    };
}

pub fn main() void {}

comptime {
    _ = if (false) struct {
        pub fn commentedOutFunction() void {}
    };
}
2 Likes

Why is if (false) necessary in this case?

It prevents the commented-out decl or field from being analyzed, in case it would generate a compile error. For decls it normally doesn’t matter because they are lazily analyzed, but fields are eagerly analyzed, so something like

comptime {
    _ = struct {
        some_field: i32 = @compileError("TODO"),
    };
}

would be an error without if (false).

(I would however second @Sze’s suggestion of using an editor that supports commenting/uncommenting multiple lines at once. Even without dedicated Zig language support, most modern editors let you duplicate the caret across multiple lines or use find/replace in a selected region to let you quickly insert or remove // from the beginning of lines.)

3 Likes