We will get this error: expected type '[*c]const [*c]const u8', found '[3][]const u8' when we use this string array in functions of that C library. I tried &my_string_array and @constCast(&my_string_array) , both don’t work.
If aNiceFunctionInC(&my_string_array) does not take the length of my_string_array as an additional argument, presumably it expects the array of pointers to be null terminated.
There is an important distinction between [_:null]?[*:0]const u8 and [_][*]const u8: the former will have a null sentinel element after the "ccc" element.
You haven’t told us which C function you are calling or how it is implemented, but since you mentioned segfaults, it sounds like it expects a null-terminated array of values. Your code doesn’t terminate your array with a null sentinel, so it might be that the C function is reading beyond the bounds of the buffer until it segfaults.
If you’re unfamiliar with sentinels in Zig, I suggest you read up on sentinel-terminated arrays, pointers and slices in the docs.
Thank you for your answer and suggestion. I think it’s more about the C function thing. I don’t think I fully understand the C function for now. I guess I will spend my own time to take a look into it and its documentation. Thanks again.
Thank you everyone. It turns out that was an unrelated issue that caused the segfault.
The C function actually take another argument to determine the length of the string array, which somehow hidden in another struct… So the original [_][*]const u8 works. The [_:null]?[*:0]const u8 works too. I guess it’s because the sentinel-terminated arrays has the same len anyways.
You should probably keep the :0 as I doubt it’s being passed an array with the length of each string, it probably only works atm because you are using string literals which are always null terminated, if you ever pass it non terminated strings you will have problems
I think the function is doing some sorts of comparison. For example, the library has a dictionary somewhere, {“aaa”, “bbb”, “ccc”, “ddd”, “eee”}, then it just checks if the strings I passed to it are one of them, so they already know the length of each possible string it should be.
But I think for memory safety reason, you are probably right. Function only knows the right strings, not other wrong ones I passed to it. It depends on how they implement the comparison, and how they handle the wrong strings with different length.
I guess I should use the sentinel-terminated arrays at least for the strings themselves.
Even if the right string is passed, if it’s not null terminated, it’s still memory unsafe.
Chances are it hashes the strings, meaning it will always read up to the null character, meaning it won’t work without it.
not sure why you think it might be memory safe if it sometimes works, not how memory safety works