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

Don nospam at nospam.com
Thu Dec 2 00:39:52 PST 2010


Bruno Medeiros wrote:
> 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.
> 

I think I can implement it. From inside a static this(), pure functions 
should never be optimised as if they were pure.
When this is done, we're just left with standard cases of 'variable is 
used before being initialized', and nothing specific to pure.


More information about the Digitalmars-d mailing list