[m-dev.] Tool for generating DU types in C

Ralph Becket rafe at csse.unimelb.edu.au
Mon Mar 22 16:53:40 AEDT 2010


Paul Bone, Monday, 22 March 2010:
> 
> > This is the sort of thing I find myself churning out all too often
> > when hacking C.
> 
> I don't know if you want review comments or not.

Indeed I do :-)

> > As an example, the following file, 'a_b_tree.du':
> > 
> >     @ type a_b_tree
> >     @ constructor a
> >     @ constructor b
> >     @ constructor branch
> >     l : a_b_tree
> >     r : a_b_tree
> >     @{
> >         if (l == NULL || r == NULL) {
> >         fprintf(stderr, "a_b_tree: branch cannot have NULL arguments.\n");
> >         }
> >     }@
> >     @ end
> > 
> > will, when run through 'gen-du-type a_b_tree.du', produce 'a_b_tree.h':
> > 
> >     /* Automatically generated from a_b_tree.du. */
> > 
> >     #if !defined(__a_b_tree_h__)
> >     #define __a_b_tree_h__
> > 
> >     typedef struct _a_b_tree *a_b_tree;
> 
> Don't hide pointers in typedefs.  In C pointers are so important that they
> should be explicit.

Can you be more explicit?  The DU type is abstract and must be a
pointer; I'm not sure what's wrong with this approach.

> > and 'a_b_tree.c':
> > 
> >     /* Automatically generated from a_b_tree.du. */
> > 
> >     #include <stdio.h>
> >     #include <stdlib.h>
> >     #include "a_b_tree.h"
> > 
> >     struct _a_b_tree {};
> > 
> >     #define _a_b_tree_a_tag 0
> >     #define _a_b_tree_b_tag 1
> >     #define _a_b_tree_branch_tag 2
> > 
> >     struct a_b_tree_a _a_b_tree_a_sentinel =
> >         { _a_b_tree_a_tag };
> > 
> >     a_b_tree
> >     a()
> >     {
> >         return (a_b_tree)&_a_b_tree_a_sentinel;
> >     }
> 
> So a constructor with no arguments actually returns a reference to a globally
> allocated cell, while below a constructor with arguments allocates a new cell
> and returns it.

Yes: since all nullary constructors have the same value there's no need
to allocate a new heap cell for each instance.

> This could be confusing, and should perhaps be made more clear
> to the programmer.

Why would the programmer need to know this?  I can certainly add
documentation to this effect.

> You should also make the sentinel object above const so that it is
> allocated in read-only memory at runtime.  The constructor should also
> return a const object, use cdecl(1) for help with the const keyword, I
> never remember the order of these keywards for declarations.

I didn't know you could have const globals in C.  Would this cause an
attempt to write to const memory to abort the program?
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at csse.unimelb.edu.au
Administrative Queries: owner-mercury-developers at csse.unimelb.edu.au
Subscriptions:          mercury-developers-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the developers mailing list