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

Peter Wang novalazy at gmail.com
Thu Jul 20 18:06:19 AEST 2023


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