logical const is a subset of transitive const

news.digitalmars.com schveiguy at yahoo.com
Fri Sep 14 20:24:06 PDT 2007


"Daniel Keep" wrote
>
> I'd always assumed it was so you could do this:
>
> class A
> {
>    int foo() { ... }
>    invariant int foo() { ... }
> }
>
> {
>    invariant(A) a = cast(invariant) new A;
>    a.foo();
> }
>
> I realise that I could have accomplished the same thing by making the
> second foo a const method, but the question is, is that always the same?
> I can't think of a case, but it's possible that sometimes the
> implementation might change or be more efficient if you've got
> invariant(this) instead of const(this).

Here is the spec:

" Invariant member functions are guaranteed that the object and anything 
referred to by the this reference is invariant."

" Const member functions are functions that are not allowed to change any 
part of the object through the member function's this reference."

A const function guarantees not to change the object.

An invariant function can only be called on objects that are declared 
invariant.  This should mean that at least the object is not going to 
change.  This also implies that the function is const.

This suggests that the compiler can make more optimizations in invariant 
functions because an invariant object is not supposed to change.  In a const 
function, there could be a mutable pointer to the same data, so the compiler 
can't make those same assumptions.

So I think this is how it works:

A
{
  invariant void ifunc();
  const void cfunc();
}

const(A) a1 = new A;
invariant(A) a2 = cast(invariant) new A;

a1.ifunc(); // error, a1 is not invariant
a1.cfunc(); // ok
a2.ifunc(); // ok
a2.cfunc(); // ok

One thing that is notably missing from the spec is how to declare a const 
member function.  As it has been stated in other threads, it is ambiguous to 
do:

const int *f();

As you don't know if f is const, or if the return value is a const pointer.

-Steve 





More information about the Digitalmars-d mailing list