[m-users.] Mercury macro trouble

Volker Wysk post at volker-wysk.de
Mon May 27 03:39:12 AEST 2024


Am Sonntag, dem 26.05.2024 um 15:01 +1000 schrieb Julien Fischer:
> Hi,
> 
> On Fri, 24 May 2024 at 22:31, Volker Wysk <post at volker-wysk.de> wrote:
> 
> > Some quotes from this list:
> > 
> > M. McDonough on 2023-07-19:
> > "After some debugging, I now suspect that I know the answer, and it's that
> > MR_list_cons isn't safe to call directly outside of a foreign_proc because
> > it can interact with the Mercury register usage."
> > 
> > Peter Wang on 2023-07-20:
> > "The problem is that the argument of MR_list_cons(), the call to
> > CreateNode(), is not evaluated before MR_list_cons() starts doing
> > anything. You should make the call CreateNode() first, assign the
> > result to a variable, then perform the MR_list_cons()."
> > 
> > M. McDonough on 2024-04-27:
> > "I just want to note this, as it's caused me issues in the past. It's a
> > bad idea to have anything other than a variable or integral expression
> > (no function calls, no macros, etc) as the argument to MR_list_cons
> > (and I would generally say any of the MR_* macros unless you've read
> > them carefully). You can end up with issues where things are executed
> > in an unexpected order, and in particular on the low-level C grades,
> > this can cause big issues with Mercury registers being clobbered
> > leading to very hard to debug issues with seemingly impossible
> > behavior."
> > 
> > I think, this is bad and should be addressed.
> > 
> > The obvious solution would be to use inline C functions with the same names
> > as the macros, instead. Gcc's statement expressions aren't needed.
> > 
> > So I'm asking the Mercury team to scrap all those macros and use inline
> > functions instead. :-)
> 
> The intended use of those macros was for the implementation of the Mercury
> system itself.  They aren't inline C function because in that role
> it's probably not
> useful for them to be inline C functions.  (To say nothing of the fact
> that when those
> macros were originally written, C did not have a standard notion of an inline
> function.)

Okay

> The secondary role of these macros as a mechanism by which users can
> manipulate lists in foreign code has arisen, more or less, by accident.

But it's documented in the "C data passing conventions" section. So it's no
accident when users want to use them...

> > No, seriously, I can understand that the Mercury team is reluctant to touch
> > those long-proven macros.
> 
> Whether those macros are appropriate for users is another question.
> As C macros, they (obviously) have all the inherent issues with C macro
> argument evaluation (as in the above examples), but that's not really a Mercury
> problem.

Again, it's documented. As M. McDonough has written, it's easy to run into
those issues, when you aren't that knowledgeable about them...

> > This leads to the second best solution: Wrap those macros in inline
> > functions. And instruct the user to use them instead of the macros. For
> > instance, like this:
> > 
> > static inline MR_Word mr_list_cons(MR_Word head, MR_Word tail)
> > {
> >    MR_Word result = MR_list_cons(head, tail);
> >    return result;
> > }
> > 
> > This should amend the problem. Or am I missing something? It seems odd to me
> > that this obvious solution hasn't been implemented already.
> 
> My suggestion would be that the list module in the standard library
> provide function
> versions of these operations (as indeed it does for the C# and Java backends).
> Users should be directed to those, instead of the runtime macros ...

Yes, that's what I have in mind. Although it applies only to those five list
processing macros.

> ... or users should just foreign export pragmas the operations they
> need to manipulate
> lists in foreign code.  As indeed you would need to do if you wanted
> to manipulate just
> about any other data structure in the Mercury standard library from
> foreign code.  This
> approach also automatically handles whether arguments need to be boxed etc.

Since you say so, I assume this is efficient. 

Having those list macros, or function equivalences of them, sure is handy.
Lists are one of the most used data structures...

Cheers,
Volker


More information about the users mailing list