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

Paul Bone pbone at csse.unimelb.edu.au
Mon Mar 22 17:34:40 AEDT 2010


On Mon, Mar 22, 2010 at 04:53:40PM +1100, Ralph Becket wrote:
> > > 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.

If it doesn't look like a pointer a programmer may forget or not realise that
they should free it when they're finished with it.  

A programmer may assume that because it doesn't look like a pointer and then it
must be a structure which should not be passed by value, the programmer will
then create a pointer (to your pointer) so that they make sure that it's passed
by reference.

These cases are relatively benign, but there are probably worse cases.

> > > 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.

So that they know if it's appropriate to call free() on this object, for example.

> > 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?

If the architecture and platform supports it.  On x86/x86_64 and Linux this is
supported.  At the very least the compiler can help check this.  Any read only
data in a program including strings used in code such as:

    printf("Hello world!\n");

This data is allocated in a different section of the program's image, the read
only data section.  On ELF systems (Linux, BSD and probably others) this is
called '.rodata' and it gets mapped to memory that is read only.

I've just tested this on x86 Linux, the result was a Segfault.  Under Windows
this is probably a General Protection Fault (the real name of the x86 interrupt
that gets triggered).

(Going off topic: The code (.text section) is also read only to prevent a
buffer overrun from modifying it.  However only recently have processors and
operating systems supported the prevention of executing the data segments
including the stack, this latest improvement is done in the name of security). 

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 489 bytes
Desc: Digital signature
URL: <http://lists.mercurylang.org/archives/developers/attachments/20100322/f3a02c58/attachment.sig>


More information about the developers mailing list