www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - syntax question on "invariant" keyword

reply Michael Kiermaier <michael.kiermaier gmx.net> writes:
I tried an example from
http://www.digitalmars.com/d/final-const-invariant.html:

*** begin Test.d ***
import std.stdio;

struct S
{
    int x;
    invariant int y;
}

void main() {
    writefln(S.sizeof); // prints 4, not 8
}
*** end Test.d ***

Compilation gives the error message
Test.d(5): statement expected to be { }, not int

So I changed the line
    invariant int y;
into
    invariant {int y;}
and now the compilation works.


Why do I need the curly braces here?
And why does the example not work? Was there a change to the syntax rules of
"invariant"?

Tanks in advance,

~michael
Jul 03 2007
next sibling parent BCS <ao pathlink.com> writes:
Reply to Michael,

 I tried an example from
 http://www.digitalmars.com/d/final-const-invariant.html:
 *** begin Test.d ***
 import std.stdio;
 struct S
 {
 int x;
 invariant int y;
 }
 void main() {
 writefln(S.sizeof); // prints 4, not 8
 }
 *** end Test.d ***
 
 Compilation gives the error message
 Test.d(5): statement expected to be { }, not int
 So I changed the line
 invariant int y;
 into
 invariant {int y;}
 and now the compilation works.
 Why do I need the curly braces here?
 And why does the example not work? Was there a change to the syntax
 rules of "invariant"?
 Tanks in advance,
 
 ~michael
 
This is getting into the ambiguity between an invariant function (that is part of design by contract) and an invariant value (that is one form of const). I think the way that it should be done is invariant(int) y;
Jul 03 2007
prev sibling next sibling parent reply Michael Kiermaier <michael.kiermaier gmx.net> writes:
BCS Wrote:

 This is getting into the ambiguity between an invariant function (that is 
 part of design by contract)
Thanks, I didn't know that "invariant" can also be used for functions;
 and an invariant value (that is one form of const).
 
 I think the way that it should be done is
 
 invariant(int) y;
I tried that, but: Test.d(6): found 'int' when expecting ')' Test.d(6): statement expected to be { }, not ) Test.d(6): found ')' instead of statement Also, http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.l arn&article_id=8217 claims that "invariant int" and "invariant(int)" are NOT the same, but "invariant int" and "final invariant(int)" are the same. I don't know if that is true.
Jul 03 2007
next sibling parent BCS <ao pathlink.com> writes:
Reply to Michael,

 BCS Wrote:
 
 This is getting into the ambiguity between an invariant function
 (that is part of design by contract)
 
Thanks, I didn't know that "invariant" can also be used for functions;
 and an invariant value (that is one form of const).
 
 I think the way that it should be done is
 
 invariant(int) y;
 
I tried that, but: Test.d(6): found 'int' when expecting ')' Test.d(6): statement expected to be { }, not ) Test.d(6): found ')' instead of statement Also, http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmar s.D.learn&article_id=8217 claims that "invariant int" and "invariant(int)" are NOT the same, but "invariant int" and "final invariant(int)" are the same. I don't know if that is true.
Are you using dmd 2.x or 1.x?
Jul 03 2007
prev sibling parent reply Daniel919 <Daniel919 web.de> writes:
Are you using dmd 1.x ? The final-const-invariant thing only works on 
the experimental 2.x version. I tried your example there and it compiles 
without errors as expected.

 Also, http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.l
arn&article_id=8217 claims that "invariant int" and "invariant(int)" are NOT
the same, but "invariant int" and  "final invariant(int)" are the same.
 
 I don't know if that is true.
"invariant(int) x" this is useless and does not mean that x can't be changed, what someone might think at first. Using brackets means that you can assign another instance of TYPE to the variable. But you can't change the data of the instance. "invariant(int) x" means: you can assign another instance of int to x You see, this doesn't make sense. It's equal useless for all simple storage classes. However, "final invariant(int) x = 1" works like "invariant int x = 1", because final means: you can't assign another int to x
Jul 03 2007
parent reply Michael Kiermaier <michael.kiermaier gmx.net> writes:
Daniel919 Wrote:

 Are you using dmd 1.x ? The final-const-invariant thing only works on 
 the experimental 2.x version. I tried your example there and it compiles 
 without errors as expected.
Well, that seems to be the problem: My dmd command reports: Digital Mars D Compiler v1.018 Where can I get the 2.x version? I cannot find it in the "download" section on the Digitalmars D hompage And what exactly is the status of 2.x? I believe I read somewhere, that D 2.0 was officially released. But now you write that it is still experimental.
 "invariant(int) x" this is useless and does not mean that x can't be 
 changed, what someone might think at first.
 Using brackets means that you can assign another instance of TYPE to the 
 variable. But you can't change the data of the instance.
 
 "invariant(int) x" means: you can assign another instance of int to x
 You see, this doesn't make sense.
 It's equal useless for all simple storage classes.
 
 However, "final invariant(int) x = 1" works like "invariant int x = 1",
 because final means: you can't assign another int to x
Thanks for the explanation! ~michael
Jul 04 2007
parent Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Michael Kiermaier wrote:
 Daniel919 Wrote:
 
 Are you using dmd 1.x ? The final-const-invariant thing only works on 
 the experimental 2.x version. I tried your example there and it compiles 
 without errors as expected.
Well, that seems to be the problem: My dmd command reports: Digital Mars D Compiler v1.018 Where can I get the 2.x version? I cannot find it in the "download" section on the Digitalmars D hompage
It's on the changelog page: http://www.digitalmars.com/d/changelog.html Be sure to click the 2.002 link, the "latest version" link seems to be out of date (points to 2.001).
 And what exactly is the status of 2.x? I believe I read somewhere, that D 2.0
was officially released. But now you write that it is still experimental.
It's an experimental alpha version. That means it's got the latest additions, but may be more buggy and later versions can change and break code that used to work.
Jul 04 2007
prev sibling next sibling parent Derek Parnell <derek nomail.afraid.org> writes:
On Tue, 03 Jul 2007 18:00:46 -0400, Michael Kiermaier wrote:

 I tried an example from
 http://www.digitalmars.com/d/final-const-invariant.html:
 
 *** begin Test.d ***
 import std.stdio;
 
 struct S
 {
     int x;
     invariant int y;
 }
 
 void main() {
     writefln(S.sizeof); // prints 4, not 8
 }
 *** end Test.d ***
 
 Compilation gives the error message
 Test.d(5): statement expected to be { }, not int
 
 So I changed the line
     invariant int y;
 into
     invariant {int y;}
 and now the compilation works.
 
 Why do I need the curly braces here?
 And why does the example not work? Was there a change to the syntax rules of
"invariant"?
 
 Tanks in advance,
 
 ~michael
This seems to work ... //----------------- import std.stdio; alias invariant int iint; // To help remove the stupid ambiguity // caused by excessively overloaded keywords struct S { int x; iint y; } void main() { writefln(S.sizeof); // prints 4, not 8 } //----------------- -- Derek (skype: derek.j.parnell) Melbourne, Australia 4/07/2007 9:12:48 AM
Jul 03 2007
prev sibling parent reply Derek Parnell <derek nomail.afraid.org> writes:
On Tue, 03 Jul 2007 18:00:46 -0400, Michael Kiermaier wrote:

 I tried an example from
 http://www.digitalmars.com/d/final-const-invariant.html:
 
 *** begin Test.d ***
 import std.stdio;
 
 struct S
 {
     int x;
     invariant int y;
 }
 
 void main() {
     writefln(S.sizeof); // prints 4, not 8
 }
 *** end Test.d ***
 
 Compilation gives the error message
 Test.d(5): statement expected to be { }, not int
 
 So I changed the line
     invariant int y;
 into
     invariant {int y;}
 and now the compilation works.
 
 Why do I need the curly braces here?
 And why does the example not work? Was there a change to the syntax rules of
"invariant"?
 
 Tanks in advance,
 
 ~michael
I get that fact that invariant struct members don't take up space in the struct (though I don't think that is a smart move) but I don't understand the results of this code below ... // ------------ import std.stdio; alias invariant int iint; struct S { int x = 9; invariant int y = 8; void foo() { // y = 7; // Expectedly, this fails to compile (GOOD). } } void main() { S a; writefln("Size of S is %s", S.sizeof); writefln("Before x=%s y=%s", a.x, a.y); a.x = 1; a.y = 2; writefln("After x=%s y=%s", a.x, a.y); } // ------------ The results I get using DMD 2.002 are ... c:\temp>test Size of S is 4 Before x=9 y=9 After x=2 y=2 -- Derek (skype: derek.j.parnell) Melbourne, Australia 4/07/2007 9:39:54 AM
Jul 03 2007
next sibling parent Robert Fraser <fraserofthenight gmail.com> writes:
 struct S
 {
     int x = 9;
     invariant int y = 8;
     void foo()
     {
         // y  = 7; // Expectedly, this fails to compile (GOOD).
     }
 }
 void main() {
     S a;
     writefln("Size of S is %s", S.sizeof);
     writefln("Before x=%s y=%s", a.x, a.y);
     a.x = 1;
     a.y = 2;
     writefln("After  x=%s y=%s", a.x, a.y);
 }
 // ------------
 The results I get using DMD 2.002 are ...
 
 c:\temp>test
 Size of S is 4
 Before x=9 y=9
 After  x=2 y=2
 
 -- 
 Derek
 (skype: derek.j.parnell)
 Melbourne, Australia
 4/07/2007 9:39:54 AM
Looks like a bug to me. A big one.
Jul 03 2007
prev sibling parent reply Daniel919 <Daniel919 web.de> writes:
 struct S
 {
     int x = 9;
     invariant int y = 8;
Instead of it, this is working: const int y = 8; static invariant int y = 8; final int y = 8; //but this takes up storage for each instance
     void foo()
     {
         // y  = 7; // Expectedly, this fails to compile (GOOD).
     }
 }
Jul 03 2007
parent Bill Baxter <dnewsgroup billbaxter.com> writes:
Daniel919 wrote:
 struct S
 {
     int x = 9;
     invariant int y = 8;
Instead of it, this is working: const int y = 8; static invariant int y = 8; final int y = 8; //but this takes up storage for each instance
     void foo()
     {
         // y  = 7; // Expectedly, this fails to compile (GOOD).
     }
 }
Looks like we should have stuck with "super const" after all. :-P --bb
Jul 03 2007