Call to immutable method during immutable construction

Jonathan M Davis jmdavisProg at gmx.com
Wed Nov 10 09:54:02 PST 2010


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

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

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

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

- Jonathan M Davis


More information about the Digitalmars-d mailing list