I need help understanding the semantics of optionals paired with pointers.
Let’s say we have the following cases:
?i32 // <-- Int that may not exist
*?i32 // <-- Pointer to int that may not exist
?*?i32 // <-- Pointer that may not exist to an int that may not exist
*?*?i32 // <-- Pointer to pointer that may not exist pointing to an int that may not exist
No, these are 2 separate types with different semantics. ?*i32 will be the closest to int * in C. Since C pointers can be null, you want the Zig type where the pointer can be null, which in this case is ?*T.
btw *?c_int is not technically compatible with the C ABI.
my limited understanding is that ?c_int is currently implemented a bit like
struct {
inhabited: bool,
payload: c_int,
};
and thus that, like all non-extern, non-packed structs, the layout of ?c_int is not considered well-defined (= part of an ABI contract that will be honored by different versions of the zig compiler or even across different compilation units in a single invocation of zig build)
Just for clarification, types should be read left-to-right:
?i32 // <-- optional i32
*?i32 // <-- pointer to an optional i32
?*?i32 // <-- optional (pointer to an optional i32)
*?*?i32 // <-- pointer to an optional (pointer to an optional i32)