digitalmars.D.learn - const/invariant
- Denton Cockburn (8/8) Dec 04 2007 given a class:
- Derek Parnell (41/53) Dec 04 2007 Dunno, except that you have to say ...
- Denton Cockburn (4/66) Dec 04 2007 You can call const member functions.
- Denton Cockburn (2/2) Dec 04 2007 declare get() const and it'll work.
- Derek Parnell (7/10) Dec 05 2007 Duh!
- Steven Schveighoffer (24/32) Dec 05 2007 const class references can be used to call const member functions, but
- Derek Parnell (19/41) Dec 05 2007 Thanks Steve, I guess this should be made clearer in the documentation.
- guslay (6/15) Dec 05 2007 I don't see any difference between const and invariant when they are con...
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)?
Dec 04 2007
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
Dec 04 2007
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: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.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.
Dec 04 2007
declare get() const and it'll work. const int get { return mbr; }
Dec 04 2007
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
Dec 05 2007
"Denton Cockburn" wrotegiven 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
Dec 05 2007
On Wed, 5 Dec 2007 10:00:28 -0500, Steven Schveighoffer wrote:"Denton Cockburn" wroteThanks 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 AMgiven 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.
Dec 05 2007
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.
Dec 05 2007