4 ms·
The idiomatic way in Zig is to return the simple unadorned error, but return detailed error data through a pointer argument passed into the function, allowing t
by quantummagic 1y ago
The idiomatic way in Zig is to return the simple unadorned error, but return detailed error data through a pointer argument passed into the function, allowing the function to fill in extra information before returning an error.
const MyError = error{ FileNotFound, PermissionDenied };
fn readFile(path: []const u8, outErrInfo: *ErrorInfo) ![]const u8 {
if (fileMissing) {
if (outErrInfo) |info| {
info.* = ErrorInfo{
.code = MyError.FileNotFound,
.message = "File missing",
.line = @line(),
};
}
return MyError.FileNotFound;
}
return data; // success
}
The advantage of this is that everything is explicit, and it is up to the caller to arrange memory usage for error data; ie. the compiler does not trigger any implicit memory allocation to accommodate error returns. This is a fundamental element of Zig's design, that there are no hidden or implicit memory allocations
- dnautics 1y agoshould be ?*ErrorInfo in the header there =D
- quantummagic 1y agoThanks. There are a few thinko/typoes in the example (which can no longer be edited), but the basic outline survived okay.
- metaltyphoon 1y agoSo… pretty much how C does it.
- dwattttt 1y agoCulture and coding standards count for a lot. C _can_ do this, but it's not normal to. If Zig can foster a culture of handling errors this way, it'll be the way the community writ large handle errors.
- mark38848 1y agoIt's still complete dogshit not to be able to have data there. Odin is much better here, iirc
- quantummagic 1y agoThe main difference is that C doesn't have error (result types) baked into the language. So the expectation would be in the Zig example above, the calling function would never even bother to inspect the error details, unless the error path was triggered by the called function.
- pjmlp 1y agoZig is basically the safety of Modula-2, with a revamped C like syntax, which is why it feels too little for a 2025 language. Naturally the comptime part is new, but I wouldn't pick a language only because of that.
- quantummagic 1y agoWell, to look at it optimistically, it's meant as a foundational language, to take over the role C still has today, of being the only true glue language that can underlie all the others. If Zig can actually take over that function, then it will be a major upgrade to the ecosystem, even though it will never be the language of choice for most projects.
- pjmlp 1y agoDespite all my bashing regarding C, I would rather keep C around with a standard -fhardening, -fsafe, or whatever, with similar constraints, enabling enums without implicit numeric conversions, standard library types for arrays and strings, no decays of arrays into pointer. Probably more than enough if we leave C as a kind of portable Assembler role, to be used as much as Assembly is, and leave everything else to safer managed languages. A model just like UNIX authors themselves have applied when creating Inferno with Limbo, with the learnings of UNIX and Plan 9. Not a fan of @, !, .{ } all over the place, or the struct based imports that look like Javascript require() instead of a proper module system.
- nextaccountic 1y ago> The advantage of this is that everything is explicit, and it is up to the caller to arrange memory usage for error data Likewise, this has the disadvantage that the caller must allocate space for the error payload, even if the error is very unlikely
- quantummagic 1y agoWell, it is an optional parameter (my typo made that unclear), so the caller may omit it if desired. The reason for this particular tradeoff, is in favour of correctness rather than convenience, eg. if the failure is in an OOM condition, it can still be reported.
- nextaccountic 1y agoOk this sounds nice. You would just need some syntax sugar to make this ergonomic (both in the side of function calling, and also in the side of the erroring function) but the fundamentals seem solid I think there's space for a post-Rust, post-Zig language to combine the approaches of both and make it possible to do away with automatic heap allocation (when needed - not every piece of code wants to bother with this), but also don't make code overly verbose when doing so.
- randyrand 1y agoIMO error objects should’ve included a pointer to some extra preallocated memory. In my C code I always allocate my error objects first, with usually 1024 bytes just for error strings. In cases where i don’t care for error strings, i allocate 0 bytes for them. I have a simple function to append error strings, and it checks for space. So all the code is ambivalent about whether this extra space exists. works wonderfully.