[m-rev.] for review: uint operations in array.m
Julien Fischer
jfischer at opturion.com
Sat Jan 3 02:02:21 AEDT 2026
On Sat, 3 Jan 2026 at 01:03, Zoltan Somogyi <zoltan.somogyi at runbox.com> wrote:
> Add uint versions of array operations.
>
> library/array.m:
> Add uint versions of most of this module's operations.
You will need to be particularly careful with this. Our target
languages impose a number of constraints on arrays.
The main two that are relevant here are that
1. In C# and Java, array index expressions have type int; indexes
of other integral types will be implicitly converted (where allowed).
2. In C# and Java, type int (both in Mercury and the target language) is a
32-bit quantity, which means that array indexes are also (signed) 32-bit
quantities.
(C is a bit more liberal in what it allows.)
The upshot of all this is that the uint array indexes and sizes do necessarily
allow you to omit check on them, becasue if a cast from uint -> int wraps around
becomes negative, we will have an abort or exception in the the target language
code instead of throwing a Mercury exception or failing.
Obviously, some operations, such as size/1 will always be safe. I've noted
one group below that definitely are not in their present form and I think
correctness arguments need to be made for some of the others.
> NEWS.md:
> Mention the new operations.
>
> library/edit_distance.m:
> Use the new array operations to eliminate a bunch of casts.
>
> library/edit_seq.m:
> Minor style fix.
>
> tests/hard_coded/array_gen.{m,exp}:
> tests/hard_coded/array_test_2.{m,exp}:
> Extend the tests of array.m's operations to the corresponding uint
> versions. Expect the output for the new versions.
>
> tests/hard_coded/array_primitives.m:
> tests/hard_coded/array_resize.m:
> tests/hard_coded/array_shrink.m:
> Extend the tests of array.m's operations to the corresponding uint
> versions, but generate output only if their results differ from the
> original int versions. (They don't differ.)
...
> @@ -948,6 +1061,7 @@
> :- import_module require.
> :- import_module string.
> :- import_module type_desc.
> +:- import_module uint.
>
> %---------------------------------------------------------------------------%
>
> @@ -1530,6 +1644,12 @@ init(Size, Item, Array) :-
> array.init_2(Size, Item, Array)
> ).
>
> +uinit(N, X) = A :-
> + array.uinit(N, X, A).
> +
> +uinit(Size, Item, Array) :-
> + array.init_2(uint.cast_to_int(Size), Item, Array).
As I mentioned above, this will be a problem. Consider, the following on a
system where int and uint are 32-bit:
array.uinit(2147483648u, "foo", Array)
Ditto for all of the predicates and functions that create an array from a given
size in some way (e.g. generate and friends).
Julien.
More information about the reviews
mailing list