general questions about static this() at module level

Ali Çehreli via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Oct 31 11:09:41 PDT 2016


On 10/31/2016 09:02 AM, WhatMeWorry wrote:

 > Thanks! If you don't mind a follow up question, is this:
 >
 > immutable uint maxSize = 128;
 >
 > identical to this:
 >
 > immutable uint maxSize;
 >
 > static this()
 > {
 >     maxSize = 128;
 >
 > }

As usual, yes and no. :)

The former is initialized at compile-time, meaning that it's burned into 
the binary program to be placed on a page for such immutable values.

The latter is initialized at run-time, meaning that its location in 
memory will be filled with the run-time computed value of the expression.

As long as we treat immutable as immutable, from the point of view of 
the program the two behave the same. If we attempt to mutate immutable 
data, the outcome is undefined. The following program demonstrates that

1) The two kinds of immutables are placed in different places in memory 
('a' is nearby 'a0' but 'b' is elsewhere)

2) Although both 'a' and 'b' are mutated, the last assert fails 
presumably because the compiler happens to treat 'a' differently from 
'b' by using its compile-time value like an enum. In other words, 
although 'a' has a place in memory and we manage to change it,

     assert(a == 43)

is compiled as

     assert(42 == 43)

and fails. That's not the same with b. Again, none of this is defined 
anywhere in the language spec. If we mutate const or immutable data, the 
behavior is undefined.

import std.stdio;

immutable uint a0 = 10;
immutable uint a = 42;
immutable uint b;

static this() {
     b = 42;
}

void info(T)(string tag, ref T t) {
     writefln("%20s: %s %s @ %s", tag, T.stringof, t, &t);
}

void mutate(alias t)() {
     info(t.stringof ~ " before", t);

     import std.traits : Unqual;
     auto p = cast(Unqual!(typeof(t))*)&t;
     *p = *p + 1;
     info(t.stringof ~ " after ", t);
}

void main() {
     info("a0 for reference", a0);
     mutate!a;
     mutate!b;

     assert(b == 43);
     assert(a == 43);  // <-- FAILS
}

May print

     a0 for reference: immutable(uint) 10 @ 69D390
             a before: immutable(uint) 42 @ 69D394
             a after : immutable(uint) 43 @ 69D394
             b before: immutable(uint) 42 @ 6A9F70
             b after : immutable(uint) 43 @ 6A9F70
core.exception.AssertError at deneme.d(851): Assertion failure

Ali



More information about the Digitalmars-d-learn mailing list