Description
Currently the type of c"aoeu"
is *const u8
.
Instead, the type should indicate that the pointer is null terminated. Here are two ideas to represent that:
*0 const u8
*null const u8
This type would be implicitly castable to *const u8
. You can explicitly cast the other way, and in debug mode this inserts a safety check to make sure there actually is a null byte there.
It should probably work for any type that supports T == 0
or T == null
.
We want to steer users away from this type and instead use []const u8
, which includes a pointer and a length. However, we still have to deal with null terminated things from C land, which makes this useful, and some kernel interfaces. For example, we currently have this:
pub fn open_c(path: *const u8, flags: usize, perm: usize) -> usize {
arch.syscall3(arch.SYS_open, usize(path), flags, perm)
}
pub fn open(path: []const u8, flags: usize, perm: usize) -> usize {
const buf = @alloca(u8, path.len + 1);
@memcpy(&buf[0], &path[0], path.len);
buf[path.len] = 0;
return open_c(buf.ptr, flags, perm);
}
Having the open_c
prototype be *0 const u8
would make it more type-safe. Further, we could provide an open
function that supported either type for path
, and if it happened to be null terminated then it could avoid the stack allocation.
We could also make the type of string literals be []0 const u8
meaning that the pointer value for the slice has a 0 after the last byte. The length would still indicate the memory before the null byte. If you slice this type then the pointer component would change from *0 const u8
to *const u8
.
It would be extra helpful if automatic .h import could identify when a pointer in a function is supposed to be null-terminated, and we could emit a compile error if the user passes a pointer that is not null terminated. I'm not sure how we could detect this automatically though.