Why does Zig panic when accessing arrays out of bounds? Can it not return Error/None?

To “fix” this issue, both OpenCascade and FreeCAD devs try to throw/catch exceptions now, however more than often, they forget to add an exception for a failure case, and everything crashes.

At least C++ allows the user to recover from the error. Hopefully Zig will too.

If you have the opportunity to catch an exception, you have the opportunity to use the API correctly. If the library you’re using accepts a value from you and uses that value to index into an array without checking it, that means the domain of the function is bound by the array size, and providing values outside the domain is a programmer error (incorrect usage of the API). That’s probably a bad API, but it is what it is.

Out of bounds array access does not panic. It invokes safety checked illegal behavior. In optimized release builds (where long runtime even in the face of programmer errors would be important) it will simply try to access the memory at the specified offset, whatever the implications of that are. In debug releases (where you are expecting to be making changes to the program) the program panics (halts) with a stacktrace to tell you how you were using an API wrong.

It would be unwise to shoehorn exception style error handling into solving the problem of handling programmer errors. It’s better to fix the root problem, and exception handling sweeps the root problem under the rug.

4 Likes

Depending on the situation it can also be a user error.

For example I once stumbled upon a program a long time ago where you used indexes into arrays in a config file.

So if the user uses a wrong index, crashing with a proper error message may be a good idea or it may not depending on what the wanted behaviour for wrong configuration is.

Crashing because of faulty user input is never a good idea, but this is a typical case of missing input validation (e.g. the problem needs be prevented before it happens, not via post-hoc error handling).

Especially because Zig range checks are not present in all build modes.

2 Likes

Regarding this issue, when an array is out of bounds, it should not be considered a recoverable error. However, I think the demand here may be that during the debugging phase, the API just wants to be able to obtain more valuable and customizable log information related to the crash point before the crash.

Although I think this problem can be solved by checking in advance before the array is out of bounds based on runtime_safety, rather than receiving the error after the crash occurs.

Yes. And that’s the reason for my CheckedSlice further up in this discussion.

I think they were saying that normally the user input would be validated before doing any slicing ops. Are you saying you validate the user input using your CheckedSlice, and then use regular slices from then on? Just trying to understand.

Pretty much.

It’s just easier to do it that way when the slice length depends on the user’s system (e.g. because of runtime known plugins).

I’ve been learning zig for a bit now, and this thread prompted me to check if there is something like rust’s slice::get in zig, but I didn’t find anything.

I do think it is worth it to include such function, similarly to how hashmap has get. A slice after all can be thought of as a mapping where the keys are consecutive numbers in the range 0..N.

This kind of .get method is not for replacing normal indexing, of course, but for the case where the index comes from a non-trusted source, like user input or non-validated data.

1 Like

Just use an if, that’s what the function would be anyway.

hashmap has a get because its a lot more complicated to get an element than it is for a slice.

It’s relatively straightforward to make out-of-bounds values into an error condition, if that’s what you want.

You do need to use a function, and not slice[i] directly, however. No way around that.