On Monday, 16 September 2013 at 16:50:43 UTC, Namespace wrote:
On Monday, 16 September 2013 at 15:47:36 UTC, ilya-stromberg wrote:
On Monday, 16 September 2013 at 15:12:05 UTC, Maxim Fomin wrote:
On Monday, 16 September 2013 at 10:29:12 UTC, matovitch wrote:
All your examples are great, thank you ! Is there a way to omit validate such that the compiler would call it implicitly ?

For example :

class C {
...
}

void fun(@nonNull C c) {
...
};

C c;
fun(c);  //compilation error since C is null

No, this isn't doable with UDAs because what you want requires runtime check. It is doable using other language features.

It's intresting how can I check that pointer is not null at the compile time. Can you print a example, please? I know that we can use contract programming, but it requires runtime check.

That isn't possible. ;)

Similar effect can be achieved by different way. If some function takes S as parameter, one cannot pass directly instance of A or null - error will be issued which is some sort of compile-time protection.

class A
{       
        int i;
}

struct S
{
    A a;
    A getA()
    {
        if (a is null)
            a = new A;
            return a;
        }
    alias getA this;
}

void main()
{
   S s;
   assert (s.i is 0);
   S ss = S.init;
   assert (ss.i is 0);
}

Unfortunately D does not have non-nullable classes which is a problem #1. Ideally structs should have default constructors (hello to those who miss them - problem #2) which could initialize class instance. Since they are absent, wrapping struct can be enhanced by inserting disabled constructor to ensure that no default struct instances with null references are created. However, since disabled constructors are also flawed (they don't prevent from producing T.init values by design and in some situations dmd is not smart enough to detect other cases by mistake) which is a problem #3, non-null classes can be simulated by code above using alias this + rt check. At least this works with two most problematic cases of struct initilialization: without initializer and with T.init value.

Reply via email to