Call to immutable method during immutable construction

Jens Mueller jens.k.mueller at gmx.de
Wed Nov 10 13:01:55 PST 2010


Jonathan M Davis wrote:
> On Wednesday, November 10, 2010 06:14:07 Jens Mueller wrote:
> > Hi,
> > 
> > according to TDPL p. 294 the following call to fun should not be
> > allowed. But it compiles and I see not why that shouldn't be allowed. I
> > think it's a bug in TDPL but I'm unsure.
> > 
> > class A {
> >     int a;
> >     int[] b;
> >     this() immutable {
> >         a = 5;
> >         b = [ 1, 2, 3 ];
> >         fun();
> >     }
> >     void fun() immutable {
> >     }
> > }
> > 
> > Any opinions?
> 
> Well, regardless of what the correct behavior is, dmd is not entirely in line 
> with TDPL yet, so there's a good chance that dmd just hasn't been updated to 
> match TDPL yet.
> 
> Now, I'd have to read the appropriate section of the book again (and I don't 
> have it on me at the moment) to be sure, but IIRC, the reasoning as to why 
> calling fun() was illegal was because all member variables must be initialized 
> in an immutable constructor only once, and they cannot be accessed before they 
> are used, so you'd have to be sure that any other functions which  were called 
> didn't access them (including any pre or post-conditions or the invariant), and 
> the compiler is supposed to take the easy and simple route of simply disallowing 
> calls to other member functions in an immutable constructor rather than trying 
> to verify that the functions being called didn't access those variables 
> (particularly since even if the functions being called didn't access any member 
> variables, the functions that _they_ call could, and it could get pretty nasty 
> to verify).

Right. That is why calling fun shouldn't be possible. So you say it's
not handled by dmd yet.

> Now, it could be that this particular situation is still legal, because the 
> compiler is able to see that you initialized all of the member variables 
> _before_ calling fun().

Right. That could also be the case. And my question is what is the case.
Is it the simple route that is not implemented at all or is it this more
advanced route that is already implemented?
I just checked by moving fun() to the beginning. Still works. Further
initializing a member in fun() is not allowed. But accessing a member in
fun works irrespective when it is called.
Actually I find this behavior better than the one defined in TDPL.

> If it's straightforward enough for the compiler to verify that you never call 
> any member functions prior to initializing all member variables in an immutable 
> constructor (and the compiler may _have_ to be able to be that smart anyway to 
> guarantee that it initializes each member variable exactly once), then I don't 
> see why it shouldn't be legal to call them after all member variables have been 
> initalized, but I don't know if the compiler has to be that smart, and in 
> reality, it's not actually valuable when you think about it. What could fun() 
> actually do which would be useful? You're not returning anything from either it 
> or the constructor, and it's immutable, so it can't alter any state anywhere. 

You mean alter A's state. It could change something outside of A, couldn't it?

> It would only make sense for it to be legal if all member variables
> had already been initialized, but at that point, there's no point to
> calling any other functions, since they'd have to be immutable and if
> they're immutable, you can't do anything with them except return a
> result, and since you're in an immutable constructor, and all member
> variables are already initialized, you can't do anything useful with
> that result.

See above.

> So, while I don't necessarily see anything wrong with calling fun() in this 
> situation being legal, I don't see the point.

My main point is that I'd like to know what is implemented as in
mentioned TDPL and what isn't.
But I agree with you that calling an immutable member function from the
immutable constructor is probably less useful.

Jens


More information about the Digitalmars-d mailing list