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