User defined attributes use

Maxim Fomin maxim at maxim-fomin.ru
Mon Sep 16 10:50:15 PDT 2013


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.


More information about the Digitalmars-d-learn mailing list