-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
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.