Continued looking at properties in D - interfaces and constraints

Antonio Corbi via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Oct 9 07:06:42 PDT 2016


On Sunday, 9 October 2016 at 11:54:50 UTC, mikey wrote:
> Hi,
>
> I'm continuing to look at properties in D and have found 
> another area where I think there may be an issue - or maybe 
> where I'm doing something wrong.
>
> I have started trying to use constraints on my properties to 
> constrain which values they can take I have also started trying 
> to use interfaces. What I noticed was that when I combine these 
> 2 features the constraints get discarded.
>
>     interface Widthy {
>         @property inout(int) width() inout;
>         @property void width(int width);
>     }
>
>     class Test : Widthy {
>     private:
>         int _w;
>     public:
>         @property inout(int) width() inout { return _w; }
>         @property void width(int width)
>         in {
>             import std.exception;
>             if (width < 0) {
>                 throw new
>                 Exception("width is less than zero");
>             }
>         }
>         body {
>             _w = width;
>         }
>     }
>
>     void main() {
>         import std.stdio;
>         auto t = new Test;
>         t.width = -1;
>         writeln("width: ", t.width);
>         // width: -1
>
>         // hmmm... not good
>     }

Hi Mikey,

I think the failure you are experimenting is a mixture of two 
problems:

1. Inheritance with contracts is evaluated in a special way, 'in 
contracts' in the base and derived method (property) are or-ed, 
so if one of them passses, the contract is believed to have 
succeeded. As you don't have a contract in the base-method: 
"@property void width(int width)", I think that the compiler 
assumes that its empty contract is always true.

So it's a matter of adding some contract to it, i.e.:

interface Widthy
{
   @property inout(int) width() inout;
   @property void width(int w) in { assert(w > 7); }
}

But then comes...

2. This approach fails with dmd version: DMD64 D Compiler v2.071.2
but it works with ldc 1.0.0 and also with ldc-git (based on DMD 
v2.071.2 and LLVM 3.8.1 ,  built with DMD64 D Compiler v2.071.2), 
so I think it's a bug in DMD, but I'm very new to D, so I hope 
that someone here with deeper knowledge can throw some light :)

Antonio



More information about the Digitalmars-d-learn mailing list