Bug in the compiler?

This code:

const std = @import("std");
const stdout = std.io.getStdOut().writer();
const HASH_SIZE: usize = 1 << 20;
const HashElem = struct {
    sig: usize,
    d: u64,
const ZHASH = HashElem{
    .sig = 0,
    .d = 0,
var hashes = [_]HashElem{ZHASH} ** HASH_SIZE;
pub fn main() !void {
    var hv: usize = 0;
    try stdout.print("{d}\n", .{hv});
    stdout.print("h={d}\n", .{hashes[0].sig}) catch unreachable;
    stdout.print("h={d}\n", .{hashes[hv].sig}) catch unreachable;

fails miserably with a SIGSEGV (compiled in Debug mode with 0.10.0).
But it works if any of these changes is made:

  1. You replace 20 by 19 in HASH_SIZE
  2. You suppress the d field in HashElem
  3. The most fun: you just comment out the last line…

I am baffled…
Anybody has an explanation?

  1. make hashes const

of course, there is no sense to have immutable array here, but it is also a “fix”.

Difference in memory layout and executable size (just an observation).
When hashes is mutable:

000000000025c008 b 490.hashes
000000000020d508 r 490.HASH_SIZE
000000000020fbb0 t 490.main
000000000020d802 r 490.main__anon_2865
0000000000207710 r 490.ZHASH

Size of executable is 1_037_136 bytes.

When hashes is immutable:

00000000012018b0 r 490.hashes
000000000220d5e8 r 490.HASH_SIZE
000000000220fc90 t 490.main
000000000220d8e2 r 490.main__anon_2865
00000000022077f0 r 490.ZHASH

Size of executable is 34_593_280 bytes.

** is compile time only operator.
This means that resulting executable should contain the entire array.
But it does not (if hashes is mutable).

hello other beug ???:

I was using a package from AUR Manjaro (LINUX) for zig 9.2 …
Following the publication, I wanted to pass zig 0.10.0
after setting up…
I recompiled my terminal management application…

Ex: the line that no longer compiles: os.tcsetattr
for this to compile, I did: os.linux.tcsetattr

On the other hand, if I take a DEV it compiles ???

Maybe because I took zig-linux-x86_64-0.10.0.tar.xz