ziglang / zig

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
https://ziglang.org
MIT License
34.75k stars 2.54k forks source link

Double star array initialization syntax not working #20930

Open nock24 opened 3 months ago

nock24 commented 3 months ago

Zig Version

0.13

Steps to Reproduce and Observed Behavior

I'm writing bare metal code for the raspberry pi 3b and when using the double star initialization syntax it seems to get stuck in an endless loop and all code after it being used doesn't run. Using @memset() works as expected

export fn kernel_main() noreturn {
    var buf = [_]u8{0} ** 10;
    buf[0] = 1;

    serial.init();
    serial.writeStr("Hello\n"); // this never runs

    while (true) {}
}

In this other case it seems like I get the same issue but instead with @memset.

serial.writeStr("debug1"); // this gets printed
var cmd_name_buf: [MAX_CMD_NAME_LEN]u8 = undefined;
@memset(&cmd_name_buf, 0);
serial.writeStr("debug2"); // this doesn't
var cmd_name_len: usize = undefined;

for (str, 0..) |char, i| {
    if (char == ' ' or i == str.len - 1) { // end of command
        cmd_name_len = i;
        break;
    }

    if (i >= MAX_CMD_NAME_LEN) return CmdParseError.InvalidCmd;
    cmd_name_buf[i] = char;
}

const cmd_name = cmd_name_buf[0..cmd_name_len];
const args_str = str[cmd_name_len + 1 ..];
lfanew commented 3 months ago

Would you please share a snippet of the code you're having issues with

nock24 commented 3 months ago

It seems manually filling the buffer with a for loop also causes this issue.

lfanew commented 3 months ago

Thanks for sharing code.

I think it's likely that the serial buffer just isn't being reliably flushed before you enter your infinite loop. You'll probably need to explicitly flush it to have it reliably print before entering your loop.

nock24 commented 3 months ago

Printing to serial works completely reliably before defining the buffer.

andrewrk commented 2 months ago

can you demonstrate that the machine code being produced here is problematic?

nock24 commented 2 months ago

This is the assembly where a 10 length u8 buffer is made and then I change the first element to 1:

adrp    x8, 101f000 <compiler_rt.rem_pio2_large.rem_pio2_large+0x600>
add     x8, x8, #0x732
ldr     x9, [x8]
str     x9, [sp]
ldrh    w8, [x8, #8]
strh    w8, [sp, #8]
mov     w8, #0x1                        // #1
strb    w8, [sp]
ldrb    w8, [sp]
 sub     x0, x29, #0x1
sturb   w8, [x29, #-1]

I also noticed that if I don't change any elements in the buffer then it works.