Difference betwee storage class and type (invariant/const)?

Christian Kamm kamm.incasoftware at shift-at-left-and-remove-this.de
Tue Jun 19 02:26:29 PDT 2007


> invariant int foo;

This is like a compile-time constant

invariant int foo = 1;
foo = 2; // Fails: foo is not an lvalue
auto fooptr = &foo; // Fails: 1 is not an lvalue

> invariant(int) foo;

This is something else and some of its behaviour I don't understand.

invariant(int) foo = 1; // typeof(foo) seems to be int?
foo = 2; // ok!
auto fooptr = &foo;
*fooptr = 3; // the docs say this should fail, but it compiles fine

Note that
invariant(int)* fooptr = &foo;
fails with "cannot implicitly convert expression (& foo) of type int* to
invariant(int)*", although the documentation says that should work.

So making a type invariant seems to have no effect on plain data at the
moment. It makes a difference for data containing references though:

struct S { int x; int* p; }
invariant(S) bar;
bar.x = 1; // ok
*bar.p = 1; // fails: not mutable

auto barptr = &bar; //typeof(barptr) is invariant(S)*
barptr.x = 2 // fails: not mutable

Note also that 
static if(is(invariant(S*) == invariant(S)*))
does not pass, but
invariant(S*) barptr2 = &bar;
static if(is(typeof(barptr2) == invariant(S)*))
passes... is there a logical explanation for that?

Cheers,
Christian


More information about the Digitalmars-d-learn mailing list