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@deneme.d(851): Assertion failure

Ali

Reply via email to