C에서 돌아온 포인터에 쓰는 .?는 검사가 아니라 단언입니다. 여기서 널은 불가능하다고 말하는 것입니다. 안전 검사 빌드에서 널이면 패닉이 나고, ReleaseFast나 ReleaseSmall에서는 정의되지 않은 동작입니다. malloc에 대해서라면 그 주장은 정의상 거짓입니다.
const p = c.malloc(n).?; // asserts non-null
const q = c.malloc(n) orelse return error.OutOfMemory;
둘째 줄은 실패를 호출자에게 반환하며, 이쪽이 정직한 버전입니다. [*c]u8을 반환하는 함수는 더 나쁩니다. 타입에 ?가 없어서 아무도 떠올리지 못하기 때문입니다. C 포인터를 옵셔널이 아닌 포인터로 강제 변환하는 것은 문법 표시가 전혀 없는 같은 단언입니다. Zig 문서는 그 경우 주소가 0이면 안전 검사 대상인 불법 동작이라고 적고 있습니다.
그래서 제가 읽는 래퍼에서는 모든 C 포인터를 먼저 옵셔널로 받고, orelse가 오류 이름을 붙입니다. 아직 정하지 못한 것은 어떤 오류냐입니다. error.OutOfMemory는 malloc에는 맞지만, 널을 반환하는 다른 많은 함수에는 틀립니다.