www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Class/struct invariants

reply bearophile <bearophileHUGS lycos.com> writes:
Are D invariants supposed to be so "relaxed"? They don't get called with
default constructors:


struct Foo {
    int x = 0;
    this(int xx) { this.x = xx; }
    invariant() { assert(x == 1); }
}
struct Bar {
    int x = 0;
    invariant() { assert(x == 1); }
}
class CFoo {
    int x = 0;
    this(int xx) { this.x = xx; }
    invariant() { assert(x == 1); }
}
class CBar {
    int x = 0;
    invariant() { assert(x == 1); }
}
void main() {
    Foo f1;                  // no asserts
    Foo f2 = Foo();          // no asserts
    // Foo f3 = Foo(0);      // asserts, good

    Bar b1;                  // no asserts
    Bar b2 = Bar();          // no asserts
    Bar b3 = Bar(0);         // no asserts

    //assert(b3);            // can't be used
    // b3.__invariant();     // asserts

    //CFoo f3 = new CFoo(0); // asserts, good

    CBar cb2 = new CBar();   // no asserts
    //assert(cb2);           // asserts, good
}


Bye,
bearophile
Jun 15 2010
next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 15 Jun 2010 21:29:27 -0400, bearophile <bearophileHUGS lycos.com>  
wrote:

 Are D invariants supposed to be so "relaxed"? They don't get called with  
 default constructors:


 struct Foo {
     int x = 0;
     this(int xx) { this.x = xx; }
     invariant() { assert(x == 1); }
 }
 struct Bar {
     int x = 0;
     invariant() { assert(x == 1); }
 }
 class CFoo {
     int x = 0;
     this(int xx) { this.x = xx; }
     invariant() { assert(x == 1); }
 }
 class CBar {
     int x = 0;
     invariant() { assert(x == 1); }
 }
 void main() {
     Foo f1;                  // no asserts
     Foo f2 = Foo();          // no asserts
     // Foo f3 = Foo(0);      // asserts, good

     Bar b1;                  // no asserts
     Bar b2 = Bar();          // no asserts
     Bar b3 = Bar(0);         // no asserts

     //assert(b3);            // can't be used
     // b3.__invariant();     // asserts

     //CFoo f3 = new CFoo(0); // asserts, good

     CBar cb2 = new CBar();   // no asserts
     //assert(cb2);           // asserts, good
 }

Default construction for structs is a weird animal in D. A struct can always be default constructed and is always initialized to s.init. This allows you to construct for instance an array of structs with simple memory copying. During default struct construction, no constructors are run (they aren't allowed anyways) and no invariants are run. What would be the point of running an invariant during default construction? The only think it could possibly do is make code like this: S s; Fail without -release, and pass with -release. I don't see the value in that. -Steve
Jun 16 2010
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Steven Schveighoffer:
 During default struct construction, no constructors are run (they aren't  
 allowed anyways) and no invariants are run.  What would be the point of  
 running an invariant during default construction?  The only think it could  
 possibly do is make code like this:
 S s;
 Fail without -release, and pass with -release.  I don't see the value in  
 that.

Thank you for your answers, I was trying to understand. Of all the examples I have shown this can be the worst: struct Foo { int x; invariant() { assert(x > 0); } } void main() { Foo f = Foo(-10); } Here I'd like the compiler to assert (at compile time or at runtime), or to refuse an invariant in structs like that, where I think D has no way to enforce it (unless you call __invariant(), but this is silly). Later I can write a "bug" report about this. Bye, bearophile
Jun 16 2010
parent bearophile <bearophileHUGS lycos.com> writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4331
Jun 16 2010
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
Steven Schveighoffer:
 What you want is to be able to disable the default constructor.  Andrei  
 has hinted it might be a future improvement on other threads.

It's a good idea. I just hope this disabling will have an explicit & readable syntax (maybe disable can be used here). Bye, bearophile
Jun 16 2010
prev sibling next sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Steven Schveighoffer <schveiguy yahoo.com> wrote:
 During default struct construction, no constructors are run (they aren't  
 allowed anyways) and no invariants are run.  What would be the point of  
 running an invariant during default construction?  The only think it  
 could possibly do is make code like this:

 S s;

 Fail without -release, and pass with -release.  I don't see the value in  
 that.

Ah, but I do. If it is an error to create an uninitialized struct of type S, then the above code is a bug, is it not? -- Simen
Jun 16 2010
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 16 Jun 2010 10:58:28 -0400, Simen kjaeraas  
<simen.kjaras gmail.com> wrote:

 Steven Schveighoffer <schveiguy yahoo.com> wrote:
 During default struct construction, no constructors are run (they  
 aren't allowed anyways) and no invariants are run.  What would be the  
 point of running an invariant during default construction?  The only  
 think it could possibly do is make code like this:

 S s;

 Fail without -release, and pass with -release.  I don't see the value  
 in that.

Ah, but I do. If it is an error to create an uninitialized struct of type S, then the above code is a bug, is it not?

Yes, but an invariant doesn't guarantee that, since it is non-existent in release mode, and a compile time error is better. What you want is to be able to disable the default constructor. Andrei has hinted it might be a future improvement on other threads. -Steve
Jun 16 2010
prev sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
bearophile wrote:
 Are D invariants supposed to be so "relaxed"? They don't get called with
default constructors:

http://d.puremagic.com/issues/show_bug.cgi?id=519 Stewart.
Jun 17 2010
parent bearophile <bearophileHUGS lycos.com> writes:
Stewart Gordon:
 http://d.puremagic.com/issues/show_bug.cgi?id=519

Thank you, then my bug 4329 is a dupe, I'll mark it so :-) Bye, bearophile
Jun 17 2010