[m-users.] Float array initialisation

Fabrice Nicol fabrnicol at gmail.com
Wed May 5 22:50:50 AEST 2021


Le mer. 5 mai 2021 à 9:08 AM, Julien Fischer <jfischer at opturion.com> a
écrit :

>
> Hi Fabrice,
>
> On Wed, 5 May 2021, fabrice nicol wrote:
>
> > I have some trouble interpreting the float-to-word/word-to-float
> > conversion issue in the particular case of array initialisation.
> >
> > This is performed by 'ML_init_array(MR_ArrayPtr array, MR_Integer size,
> MR_Word item)'  (DEV branch, array.m:1007), using an MR_Word initialiser
> 'item' in a simple loop:
> >
> >         for (i = 0; i < size; i++) {
> >             array->elements[i] = item;
> >         }
> >
> > Now, the manual says that some implementations have sizeof(MR_Float) >
> > sizeof(MR_Word), which is why lists of floats should be converted
> > using 'MR_word_to_float', as explained in the (snapshot) manual (p.
> > 109):
> >
> >     "The following fragment of C code illustrates the correct way to
> extract the head of a
> >     Mercury list of floats.
> >     MR_Float f;
> >     f = MR_word_to_float(MR_list_head(list));
> >     Omitting the call to MR_word_to_float in the above example would
> yield incorrect
> >     results for implementations where ‘sizeof(MR_Float)’ is greater than
> ‘sizeof(MR_Word)’."
> >
> > A cursory look at runtime/mercury_float.h points to it being necessary
> when MR_BOXED_FLOAT is defined.
> >
> > So one would expect that the initialiser 'item', if of float type
> > (i.e. in an 'array(float)'), would be checked as not exceeding the
> > upper bound to MR_Word, when entered in init_2/3 (array.m:1494), at
> > least if MR_BOXED_FLOAT is defined elsewhere. If this is the case, my
> > guess is that the float initialiser item will not be passed unharmed
> > to the above loop (behaviour may possibly be undefined).
> >
> > The code in array.m has been too stable and polished for over 20 years
> > now for it to be a real bug, so it must be that I did not catch
> > something.
>
> 'item' does not have type float, it has type T.
> If you have a look at the Mercury predicates that call ML_init_array(),
> e.g.
>
>      :- pred init_2(int::in, T::in, array(T)::array_uo) is det.
>      :- pragma foreign_proc("C",
>          init_2(Size::in, Item::in, Array::array_uo),
>          [will_not_call_mercury, promise_pure, thread_safe],
>      "
>          ML_alloc_array(Array, Size + 1, MR_ALLOC_ID);
>          ML_init_array(Array, Size, Item);
>      ").
>
> you'll see that the argument corresponding to 'item' is type variable,
> which as per the reference manual is passed as a value of type MR_Word.
> If you call that predicate with a float in the item position, then it
> will boxed (if required) before the call.
>
> You only need to use the MR_word_to_float and MR_float_to_word (and
> the corresponding 64-bit integer versions) when passing floats to-
> and from polymorphic Mercury data structures in C (e.g. lists, arrays
> etc).
>
> Julien.


Thanks Julien.
Aaah OK (light bulb icon).
So passing T to the C FFI is not quite the same as passing array(T) or
list(T), *despite the fact* that all of them are actually passed to C as
MR_Word (which is what misled me).
In the first case, there is an underlying boxing operation that is managed
by the compiler (if I understood you well), and in the T structure case you
are on you own with the macros.
F.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurylang.org/archives/users/attachments/20210505/30aeddbb/attachment.html>


More information about the users mailing list