Should pure functions be prevented from reading changeable immutable static variables?

Bruno Medeiros brunodomedeiros+spam at com.gmail
Mon Nov 29 10:04:10 PST 2010


On 06/11/2010 01:32, Don wrote:
> Pure functions are allowed to read immutable global variables.
> Currently, this even includes globals which are initialized from inside
> 'static this()'.
> Here's an example of how this can be a problem:
>
> immutable int unstable;
>
> pure int buggy() { return unstable; }
>
> static this() {
> // fails even though buggy is pure
> assert( buggy() == ( ++unstable , buggy() ) );
> }
>
> I suspect that such functions should be forbidden from being 'pure'.
> Note that they cannot be used in CTFE (conceptually, all other @safe
> pure functions could be used in CTFE, even though the current
> implementation doesn't always allow it).
>
> The motivation for wanting to ban them is to prevent the optimiser from
> generating bad code. But if they were disallowed, there would also be
> benefits for breaking circular module dependencies:
> * if module A imports only pure functions from module B,
> we know that the static this() of A does not directly depend on the
> static this() of module B.
> (Note though it might still depend on C, which depends on B).
> * if the static this() of module A only calls pure functions, it does
> not depend on the static this() of any other module.
>
> Probably, this would only avoid the most trivial circular module
> dependencies, so not a huge win, but still a nice bonus.

Hum, another nice catch Don!

I'm not sure I agree with the resolution though (other than perhaps as a 
temporary limitation, if the alternative is too complex to implement in 
the compiler). I mean, looking at this conceptually, there is nothing 
intrinsically wrong with the 'buggy' function being pure, the real 
problem here is that a variable is accessed before it is /properly 
initialized/. 'buggy' would be fine to use afterwards. This is not 
really specific to pure functions, the same problem can happen with a 
regular functions that have immutable changing underneath them. :S It is 
also not specific to static constructors, an identical issue can happen 
with class (non-static) constructors.

 From this, it seems the ideal solution would be to have the compiler 
analyze the code, and see if any such uninitialized access occurs, and 
issue a compiler error if it does. However, this may be too complex to 
implement, so maybe when need some simpler rules, with perhaps some 
language restrictions on what can be done in static and non-static 
constructors. Doesn't TDPL mention something related to this? Because 
otherwise this is a very big safety hazard for immutability.


-- 
Bruno Medeiros - Software Engineer


More information about the Digitalmars-d mailing list