fredoverflow
fredoverflow

Reputation: 263260

Changing immutable members inside the constructor

void increment(ref int i)
{
    ++i;
}

class Class
{
    immutable int member;

    this(int parameter)
    {
        member = parameter;
        ++member;           // okay
        increment(member);  // compile-time error
    }
}

Why is ++member okay, but increment(member) isn't? Shouldn't both behave the same way?

Upvotes: 3

Views: 185

Answers (3)

Peter Alexander
Peter Alexander

Reputation: 54290

What if increment was this?

int* p;
void increment(ref int i)
{
    p = &i;
}

Uh oh, you've created a mutable reference to immutable data, breaking the type system.

Upvotes: 3

Pawel Zubrycki
Pawel Zubrycki

Reputation: 2713

I am guessing that

this(int parameter) {
    member = parameter;
    ++member;
}

is an equivalent of

Class(int parameter): member(parameter+1) {}

in C++.

I think member field is not truly mutable in constructor, so compiler can optimize it to just init it. But it cannot do it with call to another function.

PS. It works on ideone: http://ideone.com/5ym5u

Upvotes: 0

user541686
user541686

Reputation: 210705

Probably because the reference to increment isn't scope, so it has the potential to be escaped past the scope of the constructor, which would break the immutability of member, and the compiler can't verify that it's fine.

(It might be that scope won't work either, but it should. If implemented properly, I think scope would fix a lot of bugs like these, as well as providing for interesting optimizations. If it doesn't, I'd say it's a bug.)

I've pointed out semi-similar bugs before, but with delegates.
Const/immutable do have such problems in D.

Upvotes: 5

Related Questions