NotNull pointers

Walter Bright newshound2 at digitalmars.com
Mon Aug 29 13:22:52 PDT 2011


For the latest dmd, 
https://github.com/D-Programming-Language/dmd/commit/1193f7828b444056c943742daae0a5ccf262272e 
,
  I've implemented the ability to disable default initialization. This makes it 
practical to implement a library based "NotNull" type without a special syntax 
for it. The rationale for this is (rather than making it builtin) one can now 
build any type that is a restricted subset of another type. I suspect that a 
non-null type is just scratching the surface of this ability.

Here's a draft prototype of the NotNull type:

import std.c.stdio;

struct NotNull(P) if (is(typeof({P p = null;})))
{
     P p;

     this() @disable;

     this(P q)
     {
         assert(q);
         p = q;
     }

     NotNull opAssign(P q)
     {
         assert(q);
         p = q;
         return this;
     }

     alias p this;
}

void main()
{
     int x;
     NotNull!(int*) s = &x;
     *s = 3;
     printf("test1 %d\n", *s);
     s++;
     printf("test2 %d\n", s[-1]);
}

What it does is:
1. disallows instantiation with any type that null doesn't implicitly convert to
2. disables default construction (this is the new feature)
3. intercepts construction and assignment to enforce not-nullness
4. uses alias this to forward the rest to the wrapped pointer type

For example, try this:

void main()
{
     NotNull!(int*) s;
// Error: variable test.main.s initializer required for type NotNull!(int*)
}

I do think that the "this() @disable;" is an ugly syntax, and I cringe when 
seeing it. But I can't think of anything better. It does make logical sense 
given the existence of default construction syntax and the @disable, so in a 
sense it is just connecting existing dots, which has a compelling value.


More information about the Digitalmars-d mailing list