[m-dev.] C types from .m files, optimisation files, references, and everything...

Warwick Harvey wharvey at cs.monash.edu.au
Mon Aug 23 11:53:07 AEST 1999


I was wondering whether it was possible to share a C type defined in one 
Mercury module with other Mercury modules?  I expect the correct answer is 
"Stick it in a `.h' file."  And that's what I'll probably end up doing.  But 
if anybody is interested, I wouldn't mind some opinions on some of the 
issues solving the "real" problem I'm working on.

In the HAL implementation, we use a couple of quite ugly hacks and exploit 
undocumented features to get what we want.  :-)  One of these hacks was used 
in the implementation of global variables, and we just discovered that the 
hack appears to have been broken back in April or so (we only just noticed 
because some other features have been added to HAL so that now global 
variables actually start being useful).  Anyway, I can see three (or so) 
ways of fixing the implementation, with varying levels/kinds of hackiness, 
plus some efficiency issues.  But I'm getting ahead of myself...

The hack in question involves getting access to the ME_Reference C type 
defined in extras/references/reference.m.  Basically, we want static 
ME_References, not ones allocated on the heap (which is where the reference 
module puts them).  At the time I was first doing this, it seemed like the 
sort of stuff we wanted to do was too ugly to go into the Mercury 
distribution, and I wanted to avoid double-maintenance as much as possible, 
so I looked for a compromise.  The solution I came up with was to turn on 
inter-module optimisation, and lo, any module importing the reference module 
suddenly had access to anything defined in the c_header_code sections; in 
particular, the ME_Reference type.  :-)

This seemed to work fine, but it doesn't any more.  The problem is that the 
c_header_code from imported modules now appears to be inserted *after* the 
c_header_code from the importing module.  This means I'm trying to use the 
type before it's defined.  :-(  The "minimal" fix would presumably be to 
change the compiler so that it spits the c_header_code chunks out in a 
different order.  That of course isn't a particularly "nice" solution, and 
has the drawback that I have been unable to find the part of the compiler 
that does this.  :-)  (Note that just reversing the chunks would not work 
since then multiple chunks from the one original file would come out in 
reverse order, which would no doubt cause problems.)

The other two solutions I see leave the compiler as it is, and stop using 
the hack (which is presumably a good thing ;-).  One also leaves the 
references module as it is, but takes a slight performance hit (some 
unnecessary code during program initialisation, and an extra pointer 
dereference each time the global variable is accessed).  The other basically 
keeps the global variable implementation as it is, but adds some ugliness to 
the interface of the reference module (though this could presumably be 
"hidden" from the average user by putting it in a second interface section).

In the first version, we let the reference module put the data structure on 
the heap, and keep a pointer to it in a static variable, instead of having 
the structure in a static variable (we need a static way to access the 
reference since we don't pass it around as an argument).  This means an 
extra dereference each access, which is *probably* not that big a deal, but 
would be nice to avoid.

In the second version, we move the definition of the ME_Reference structure 
into a header file, so that other modules can declare variables of that 
type.  This would allow us to avoid the extra indirection at each reference, 
but makes the interface messier and maintaining abstraction harder.  Still, 
I expect something could be arranged using the C preprocessor (e.g. a couple 
of #defines before the #include) that would mean the user wouldn't need to 
rely on very much at all.

I'm thinking this last version is probably the way to go (at least for us at 
this time --- assuming I can get a suitable abstraction working for the C 
part), but I'd appreciate any thoughts you have on any of the above.  
Assuming nobody dissuades me from my current direction, I'll probably post a 
more concrete proposal in a few days (or when it's ready ;-), at which point 
it'll be easier to see what the problems are.


mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au

More information about the developers mailing list