<div dir="auto"><div><br><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Le mer. 5 mai 2021 à 9:08 AM, Julien Fischer <<a href="mailto:jfischer@opturion.com">jfischer@opturion.com</a>> a écrit :<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
Hi Fabrice,<br>
<br>
On Wed, 5 May 2021, fabrice nicol wrote:<br>
<br>
> I have some trouble interpreting the float-to-word/word-to-float<br>
> conversion issue in the particular case of array initialisation.<br>
> <br>
> 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:<br>
> <br>
>         for (i = 0; i < size; i++) {<br>
>             array->elements[i] = item;<br>
>         }<br>
> <br>
> Now, the manual says that some implementations have sizeof(MR_Float) ><br>
> sizeof(MR_Word), which is why lists of floats should be converted<br>
> using 'MR_word_to_float', as explained in the (snapshot) manual (p.<br>
> 109):<br>
> <br>
>     "The following fragment of C code illustrates the correct way to extract the head of a<br>
>     Mercury list of floats.<br>
>     MR_Float f;<br>
>     f = MR_word_to_float(MR_list_head(list));<br>
>     Omitting the call to MR_word_to_float in the above example would yield incorrect<br>
>     results for implementations where ‘sizeof(MR_Float)’ is greater than ‘sizeof(MR_Word)’."<br>
> <br>
> A cursory look at runtime/mercury_float.h points to it being necessary when MR_BOXED_FLOAT is defined.<br>
> <br>
> So one would expect that the initialiser 'item', if of float type<br>
> (i.e. in an 'array(float)'), would be checked as not exceeding the<br>
> upper bound to MR_Word, when entered in init_2/3 (array.m:1494), at<br>
> least if MR_BOXED_FLOAT is defined elsewhere. If this is the case, my<br>
> guess is that the float initialiser item will not be passed unharmed<br>
> to the above loop (behaviour may possibly be undefined).<br>
> <br>
> The code in array.m has been too stable and polished for over 20 years<br>
> now for it to be a real bug, so it must be that I did not catch<br>
> something.<br>
<br>
'item' does not have type float, it has type T.<br>
If you have a look at the Mercury predicates that call ML_init_array(),<br>
e.g.<br>
<br>
     :- pred init_2(int::in, T::in, array(T)::array_uo) is det.<br>
     :- pragma foreign_proc("C",<br>
         init_2(Size::in, Item::in, Array::array_uo),<br>
         [will_not_call_mercury, promise_pure, thread_safe],<br>
     "<br>
         ML_alloc_array(Array, Size + 1, MR_ALLOC_ID);<br>
         ML_init_array(Array, Size, Item);<br>
     ").<br>
<br>
you'll see that the argument corresponding to 'item' is type variable,<br>
which as per the reference manual is passed as a value of type MR_Word.<br>
If you call that predicate with a float in the item position, then it<br>
will boxed (if required) before the call.<br>
<br>
You only need to use the MR_word_to_float and MR_float_to_word (and<br>
the corresponding 64-bit integer versions) when passing floats to-<br>
and from polymorphic Mercury data structures in C (e.g. lists, arrays<br>
etc).<br>
<br>
Julien.</blockquote></div></div><div dir="auto"><br></div><div dir="auto">Thanks Julien. </div><div dir="auto">Aaah OK (light bulb icon). </div><div dir="auto">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). </div><div dir="auto">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. </div><div dir="auto">F.</div><div dir="auto"></div></div>