Difference between String.unsafe_set and String.set

The String.unsafe_set function is not documented but I saw it recently used in an Ocaml project. What is the difference with String.set ?

(In the same vein, what about Array.unsafe_get, Array.unsafe_set, String.unsafe_get)

The unsafe functions don’t do bounds-checking. If you give them an index outside of the string or array you’re operating on, it’ll just do its thing anyway. This won’t necessarily fail immediately, instead you’ll read or write some data that belongs to something else (or to nothing at all) and likely cause a failure in an entirely different part of your program.

This is a big source of security vulnerabilities and causes errors that are very hard to debug, so make sure you know what you’re doing before you decide to use them.

1 Like

In OCaml, we have a boundary check. You can find the code when you use Array.get at this line. Otherwise, for Array.unsafe_get, you use this function.

1 Like

Might it be worth to change the safe functions to return Option or Result to reflect the possibility of failure?

I realise changes to the standard libraries don’t happen easily.

you can implement it in your own code, using a try/with construct :

let my_array_get arr i=try Some(Array.get arr i) with _->None;; 

Of course I can.

My proposition is about whether it’s worth-while having such functionality built into the standard library. Most people want the safe functions, so if this was made now, one could make a String and StringRaw for example. String is safe and StringRaw isn’t for those seeking performance. Nudge to @c-cube for his containers and the Batteries devs.

Containers is an extension of the stdlib, so it won’t remove or hide String.unsafe_set (or, as one should use, Bytes.unsafe_set). I think the name is pretty explicit about this function being for people who know what they do :wink:

1 Like

As a stylistic advice, catching Invalid_argument _ exception is generally not a good idea: these exceptions indicate that the caller did not respect some of the precondition expected by the function. It is thus preferable to check these preconditions before hand rather than catch the exception after the fact. In other words

let find array n = if n < Array.length array && n>=0 then Some array.(n) else None