self-referential invariant member

Neil Vice psgdg at swiftdsl.com.au
Wed Feb 6 16:16:22 PST 2008


"Steven Schveighoffer" <schveiguy at yahoo.com> wrote in message 
news:focfbh$2qn0$1 at digitalmars.com...
> "Neil Vice" wrote
>>I am attempting to provide a constant instance of a struct as a member of 
>>the struct (in 2.010) and am getting unexpected compiler errors. Can 
>>someone explain what the compiler thinks I'm trying to do here and/or how 
>>I'd go about achieving what I want if it's possible?
>>
>> The following code:
>>
>>    struct Test
>>    {
>>        public invariant Test Default;
>>    }
>>
>>    void main()
>>    {
>>        Test test = Test.Default;
>>    }
>>
>
> Invariant members are not automatically static (though they should be). 
> The compiler is choking because it can't determine what a 'Test' is 
> because you are defining it as a member of each instance.

Hmm I did try declaring them specifically static as well but with no 
success. Given that the documentation for invariants didn't include any 
static examples (which I expected to be a pretty standard case) I assumed 
they were automatically static.

> In addition, you are going to have problems on Test test = Test.Default 
> because you are not allowed to automatically copy an invariant or const 
> struct to a mutable struct in case the struct has a pointer in it. 
> However, I think Walter and co. are working on getting this to work.

Yeah I'm really struggling to work with the current const system. There are 
some constructs they just don't work well with (e.g. opApply) and as much as 
I love the safety provided by const/invariant declarations I think I've 
still yet to be successful in actually finding a use for them that doesn't 
require an explicit duplication.

Having said that, are structs not copied on assignment in D? I would have 
expected the assignment to duplicate Test.Default at least for structs.

> What you probably want to do is:
>
> enum Test Default = {...};
>
> as enum is now the preferred method for manifest constants.

That was the solution I came to, but as mentioned in my previous post this 
causes the compiler to crash with a stack overflow; obviously this will 
eventually be fixed. Why two methods for defining consts are required though 
I don't understand. Why should there be any difference between an invariant 
and an enum-style manifest const? Along similar lines I don't see the reason 
to have a "ref const" variable. Should consts not automatically be passed by 
reference as an optimisation? Are "in" parameters really passed by value 
(though I guess the distinction is only for structs)?

I also wish I understood what was going on with the compiler trying to 
access opCall when I attempt access an invariant declared as follows:

    public invariant Test Default = {};

I wonder if it relates to the property/method dichotemy or whether it's 
treating {} as an inline delegate even though there's no way to initialise a 
Test to a delegate...

Thanks for your reply,

Neil 




More information about the Digitalmars-d-learn mailing list