In the code below I am trying to consume user input and process it well enough for std.posix.execvpeZ
. However, I am confused as to why both arguments[0..]
and &arguments
give exactly the same type:
const command_null: [*:0]const u8 = @ptrCast(command[0..command.len].ptr);
var arguments: [10:null] ?[*:0]const u8 = undefined;
arguments[0] = @ptrCast(command[0..command.len].ptr);
var i: u8 = 1;
while (command_tokens.next()) |argument| {
if (i >= 10) break;
var ptr2: [*]u8 = @constCast(argument.ptr+argument.len);
ptr2[0] = 0;
arguments[i] = @ptrCast(argument[0..argument.len].ptr);
i += 1;
}
arguments[i] = null;
std.debug.print("command {s} \n", .{command_null});
std.debug.print("arguments: {s} \n", .{arguments[0].?});
std.debug.print("arguments: {s} \n", .{arguments[1].?});
std.debug.print("arguments: {?*} \n", .{arguments[2]});
std.debug.print("arguments: {} \n", .{@TypeOf(arguments)});
std.debug.print("arguments: {} \n", .{@TypeOf(&arguments)});
std.debug.print("arguments: {} \n", .{@TypeOf(arguments[0..])});
const child_pid = std.posix.fork() catch |err| return err;
if (child_pid == 0) {
std.posix.execvpeZ(command_null, arguments[0..], &envp) catch return 0;
}
The output of the last 3 prints is:
arguments: [10:null]?[*:0]const u8
arguments: *[10:null]?[*:0]const u8
arguments: *[10:null]?[*:0]const u8
To be honest, I probably don’t exactly read well the pointer syntax and types in Zig, yet. so what I understand is that:
- [10:null] is an array of 10 elements. After the 10th elemnt there is null sentinel value.
- &T should give me an address of the first element, which in my understanding should be a pointer to the first
?[*:0]const u8
. - [0…] should be a slice pointer, so technically it should become something like
*[10]?[*:0]const u8
I bet a pack of chocolate milk and a pack of crayons that I am wrong on both (2.) and (3.) .
Can someone please explain?