Thread overview
syntax question on "invariant" keyword
Jul 03, 2007
Michael Kiermaier
Jul 03, 2007
BCS
Jul 03, 2007
Derek Parnell
Jul 03, 2007
Derek Parnell
Jul 04, 2007
Robert Fraser
Jul 04, 2007
Daniel919
Jul 04, 2007
Bill Baxter
July 03, 2007
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
July 03, 2007
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;


July 03, 2007
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
July 03, 2007
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
July 04, 2007
> 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.
July 04, 2007
> 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).
>     }
> }

I already wrote a bug report: #1312
July 04, 2007
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).
>>     }
>> }
> 
> I already wrote a bug report: #1312


Looks like we should have stuck with "super const" after all.  :-P

--bb