[m-users.] Using MR_list_cons inside of C functions

M McDonough foolkingcrown at gmail.com
Thu Jul 20 18:53:00 AEST 2023


Wouldn't it be possible to assign the cons head argument to a local
variable first thing in MR_list_cons? Or would that break other
things/not fix the same case with the tail argument?

On Thu, Jul 20, 2023 at 1:06 AM Peter Wang <novalazy at gmail.com> wrote:
>
> On Tue, 18 Jul 2023 18:48:55 -0700 M McDonough <foolkingcrown at gmail.com> wrote:
> >
> > :- pragma foreign_code("C", "
> > // Note that this is NOT a foreign_proc, but it is recursive, it
> > // calls Mercury code, and it also uses MR_list_cons.
> > MR_Word CreateNode(const struct C_Node *c_node){
> >     MR_Integer i;
> >     MR_Word child_nodes = MR_list_empty();
> >     // Iterate in reverse because we are constructing a list in reverse.
> >     i = c_node->num_children;
> >     while(i--){
> >         child_nodes = MR_list_cons(
> >             CreateNode(node->children + i),
> >             child_nodes);
> >     }
>
> There are piles of macros.
>
> 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().
>
> I'm not sure if we should fix or just document this problem with
> MR_list_cons() and similar macros. The fix would require use of GCC's
> statement expressions extension. In other cases where we've used
> statement expressions, we have a portable fallback that uses a function
> instead of a macro, but that requires code duplication.
> Or perhaps we can rely on function inlining?
>
> Peter


More information about the users mailing list