[m-dev.] For review: Using MR_TypeCtorInfo for generated type_ctor_infos

Warwick Harvey wharvey at cs.monash.edu.au
Fri Aug 6 17:54:40 AEST 1999

Fergus wrote:
> On 05-Aug-1999, Warwick Harvey <wharvey at cs.monash.edu.au> wrote:
> > Fergus wrote:
> > > Changing just the hand-defined ones might still lead to problems,
> > > because the compiler creates compiler-generated declarations for
> > > uses of the hand-defined ones, and these declarations might conflict
> > > with the hand-defined definitions.
> > 
> > Yes, it does and they do (which is why I changed the compiler-generated 
> > declarations), but I found a solution to that: #define the 
> > compiler-generated type to `MR_TypeCtorInfo_struct' for any hand-defined 
> > type_ctor_infos.
> Is that sufficient?  Won't that lead to conflicting definitions for
> `struct MR_TypeCtorInfo_struct'?  I think the compiler-generated
> declarations of the hand-defined type_ctor_infos will contain
> compiler-generated _definitions_ of their types, and I think these
> definitions will conflict with the hand-defined definition of that struct.

I think we're just not understanding each other, due to far too many 
independent things which may or may not be compiler generated, and which 
have declarations and definitions...  :-)  The entities we seem to be 
dealing with here are:  the name of the type_ctor_info object, the 
initialised contents of the type_ctor_info object, the name of the type used 
for the type_ctor_info object, and the contents of that type.

In hand-generated type_ctor_infos, the user provides the initialised 
contents of the type_ctor_info object.  Currently the user also provides the 
contents of the type used, but we want to change that to use the 
MR_TypeCtorInfo type instead.  The compiler thinks it knows the name of the 
type to use, and uses this name to generate declarations for the object, but 
it does *not* generate the contents of the type.  So the only disagreement 
between the user and the compiler is over the name of the type used.  If one 
provides a #define to map the name the compiler uses to the name the user 
used, then there is no problem.

To provide a specific example, `mercury_data___type_ctor_info_int_0' is now 
defined using the type `struct MR_TypeCtorInfo_struct', but the compiler 
still generates declarations (but never definitions) of it using `struct 
mercury_data___type_ctor_info_int_0_struct'.  This is fine if we just

#define mercury_data___type_ctor_info_int_0_struct      

as per my original diff.

> > Anyway, I've done some more experimentation, and appear to have eliminated 
> > all the warnings I introduced.  I did it by adding casts to `String' to all 
> > the generated `string_const' calls.
> This is not the right fix, I think.

... which is why I raised this issue in my original post, to get guidance on 
the right way to fix this.  None was forthcoming, so off I trotted on my 
own, and by all accounts in the wrong direction.

This reminds me of the classic technique for getting a reply to a question 
posted to USENET: post an obviously wrong answer to your question from a 
different account.  :-)

> It may happen to work, but it breaks invariants that the compiler
> relies on, so even if it does work it may cause problems for maintenance.
> The invariants in question are these:
> (1) the compiler should know the type of every field that it initializes
> (2) the compiler should know the type of every expression that it generates

> Previously, the compiler assumed that the arguments of a type_ctor_info
> struct were all `Word'; this is indicated by the `uniform(no)' in the
> following code

Perhaps one of the reasons I had trouble seeing "the right way" to fix the 
problem is that I don't think the above statement has been true for at least 
12 months.  If I remember correctly, ever since I first encountered a 
base_type_info (as they were then called), they have contained fields of 
type `Integer' and `Word *'.  I was surprised that the "uniform" code was 
being used, but figured I just did not understand what "uniform" meant.  It 
seemed to be extracting the type from the actual argument, and the actual 
argument was a string constant... which was being treated as a `Word *' 
rather than a `String'.  So the problem seemed to me not so much that I'd 
changed the type of the field, but that the compiler seemed to be calling an 
apple a pear...  So I tried to disabuse it by telling it that string 
constants should be of type `String' rather than `Word *'.

> By changing the definition of the type_ctor_info struct without changing
> this `uniform(no)', you broke (1).  This is what caused the compiler warnings.
> Your proposed fix to insert a cast in the generated code for `string_consts'
> without changing llds_const_type/2 accordingly breaks (2).

But the mail you replied to *does* change llds_const_type.  As I discovered 
later, without it I do get a different set of warnings, as then (2) would 
indeed be broken, as you say.

> I think a fix which maintained invariants (1) and (2) would be better
> than your proposed change.

I actually happen to think that my change (with just one tweak - changing 
`string_const()' to cast to `String' rather than `Word *' so the other casts 
to `String' are not longer necessary) does *not* violate either of these 
invariants.  That's not to say I necessarily think it's the best solution, 
but you'd need to convince me that it does in fact violate invariants, or 
has problems for other reasons, before I throw away the substantial effort 
I've put into it and try something different.

Of course there's still the following question: is there a particular reason 
why string constants should be of type `Word *' rather than `String'?


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