Thread overview | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
December 05, 2007 const/invariant | ||||
---|---|---|---|---|
| ||||
given a class: class C {} what's the difference between: const C c = new C; and invariant C c = new C; From what I can see, neither are modifiable. So what's different (D2.008)? |
December 05, 2007 Re: const/invariant | ||||
---|---|---|---|---|
| ||||
Posted in reply to Denton Cockburn | On Wed, 5 Dec 2007 06:46:21 +0000 (UTC), Denton Cockburn wrote: > given a class: > > class C {} > > what's the difference between: > > const C c = new C; > and > invariant C c = new C; > > From what I can see, neither are modifiable. So what's different (D2.008)? Dunno, except that you have to say ... const C c = new C; invariant C d = cast(invariant Foo)new C; And what I don't get is why would anyone bother with const/invariant for classes since you can't invoke any member functions when you do. -------------- class Foo { int mbr; this() { mbr = 6174; } int get() {return mbr; } } void main() { const Foo c = new Foo(); int a; a = c.get(); } -------------- I get the error messages ... : function test.Foo.get () does not match parameter types () : Error: c.get can only be called on a mutable object, not const(Foo) Aside from the useless message text "function test.Foo.get () does not match parameter types ()" that doesn't actually tell me the problem is, I can't see why this is forbidden. I can see that get() doesn't change anything but the compiler still will not let me call it. So if one can't call any member function in the const object, what is the point of it? Sure I can cast the const away but why would I want to do that for every invocation of a member function? I really don't get the point of const objects when implemented this way. I thought it might be a way to tell the compiler that I can't call member functions that happen to change member values. That would make sense to me. -- Derek (skype: derek.j.parnell) Melbourne, Australia 5/12/2007 6:20:05 PM |
December 05, 2007 Re: const/invariant | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell |
On Wed, 05 Dec 2007 18:30:37 +1100, Derek Parnell wrote:
> On Wed, 5 Dec 2007 06:46:21 +0000 (UTC), Denton Cockburn wrote:
>
>> given a class:
>>
>> class C {}
>>
>> what's the difference between:
>>
>> const C c = new C;
>> and
>> invariant C c = new C;
>>
>> From what I can see, neither are modifiable. So what's different
>> (D2.008)?
>
> Dunno, except that you have to say ...
>
> const C c = new C;
> invariant C d = cast(invariant Foo)new C;
>
>
> And what I don't get is why would anyone bother with const/invariant for classes since you can't invoke any member functions when you do.
>
> --------------
> class Foo
> {
> int mbr;
>
> this() { mbr = 6174; }
> int get() {return mbr; }
> }
>
> void main()
> {
> const Foo c = new Foo();
> int a;
>
> a = c.get();
> }
>
>
>
> --------------
> I get the error messages ...
>
> : function test.Foo.get () does not match parameter types () : Error:
> c.get can only be called on a mutable object, not const(Foo)
>
> Aside from the useless message text "function test.Foo.get () does not
> match parameter types ()" that doesn't actually tell me the problem is,
> I can't see why this is forbidden. I can see that get() doesn't change
> anything but the compiler still will not let me call it.
>
> So if one can't call any member function in the const object, what is the point of it? Sure I can cast the const away but why would I want to do that for every invocation of a member function? I really don't get the point of const objects when implemented this way.
>
> I thought it might be a way to tell the compiler that I can't call member functions that happen to change member values. That would make sense to me.
You can call const member functions.
Since the 2.008 changes, I'm missing the use of invariant for things that are passed by ref, like arrays and objects.
|
December 05, 2007 Re: const/invariant | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | declare get() const and it'll work. const int get { return mbr; } |
December 05, 2007 Re: const/invariant | ||||
---|---|---|---|---|
| ||||
Posted in reply to Denton Cockburn | On Wed, 5 Dec 2007 07:43:14 +0000 (UTC), Denton Cockburn wrote: > declare get() const and it'll work. > > const int get { return mbr; } Duh! </me slaps forehead> Ummm, yeah that makes sense. -- Derek Parnell Melbourne, Australia skype: derek.j.parnell |
December 05, 2007 Re: const/invariant | ||||
---|---|---|---|---|
| ||||
Posted in reply to Denton Cockburn | "Denton Cockburn" wrote
> given a class:
>
> class C {}
>
> what's the difference between:
>
> const C c = new C;
> and
> invariant C c = new C;
>
> From what I can see, neither are modifiable. So what's different
> (D2.008).
const class references can be used to call const member functions, but cannot call normal member functions or invariant member functions.
invariant class references can be used to call const or invariant member functions, but not normal member functions.
normal class references can call normal member functions and const member functions, but not invariant member functions.
In your example, there is no other non-const reference of c, so technically, it is invariant because nothing outside of the c reference can ever change it. Therefore, the second declaration is more accurate and gives you more ability (you can now call invariant functions).
if you had something like:
C c = new C;
const C c2 = c;
invariant C c3 = cast(invariant)c; // this is bad
Now, c2 cannot be declared invariant because something using the c reference could modify the data. c2 is like a read only view of c, it can look but cannot touch. c3 is bad because before you cast to invariant, you must ensure that no other references to the same data can modify the class.
Anticipating your next question: what is the difference between invariant and const functions? Code-wise, nothing. However, the compiler is free to make better optimizations knowing that none of the members of the class will change.
-Steve
|
December 05, 2007 Re: const/invariant | ||||
---|---|---|---|---|
| ||||
Posted in reply to Denton Cockburn | > > class C {} > > what's the difference between: > > const C c = new C; > and > invariant C c = new C; > I don't see any difference between const and invariant when they are constructed locally, like in your example. The compiler know they can't change. There is a difference however when they are passed as argument to a function. void foo( const/invariant int* x ) {...} In the const case, the value refered by x can be modified between the beginning and the end of the function. Not directly, but indirectly, either by aliasing (see http://www.digitalmars.com/d/const3.html) or in maybe if x is shared between threads. Invariant are guaranteed to never change, directly or indirectly. It's my understanding. I hope i'm not spreading too much wrongness. |
December 05, 2007 Re: const/invariant | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Wed, 5 Dec 2007 10:00:28 -0500, Steven Schveighoffer wrote: > "Denton Cockburn" wrote >> given a class: >> >> class C {} >> >> what's the difference between: >> >> const C c = new C; >> and >> invariant C c = new C; >> >> From what I can see, neither are modifiable. So what's different >> (D2.008). > > const class references can be used to call const member functions, but cannot call normal member functions or invariant member functions. > > invariant class references can be used to call const or invariant member functions, but not normal member functions. > > normal class references can call normal member functions and const member functions, but not invariant member functions. Thanks Steve, I guess this should be made clearer in the documentation. Maybe a table such as ... "Can Call" Table: Member Function Instance Declaration+----------------------------+ -------------------| normal | const | invariant | ----------+--------+-------+-----------+ normal | Y | Y | N | ----------+--------+-------+-----------+ const | N | Y | N | ----------+--------+-------+-----------+ invariant| N | Y | Y | ----------+--------+-------+-----------+ -- Derek (skype: derek.j.parnell) Melbourne, Australia 6/12/2007 9:41:44 AM |
Copyright © 1999-2021 by the D Language Foundation