bearophile <[email protected]> wrote:

Simen kjaeraas:

bearophile <[email protected]> wrote:

> Simen kjaeraas:
>
>> Much more likely would be the idea that has been discussed, of opt-in
>> non-nullness, by disabling the default constructor for a struct that
>> wraps a pointer.
>
> I am not sure that's enough.

Could you please show a case where it isn't?

We have discussed this a lot in past, I repeat because in this newsgroup I have learnt that sometimes you need to repeat things many times before most people start to notice.

First of all it's a matter of syntax. Attaching a "@" to a reference/pointer type to turn it into a nonnullable is not the same thing as using a special struct:

class T {}
T nullable_reference;
T@ nonnullable_reference = new T@();

struct S {}
S nullable_pointer;
S@ nonnullable_pointer = new S@();

void foo(T@ x) { ... }


A handy short syntax is able to turn something from a seldom used feature, to an idiom most people in the community use. Python language designers have understood this well.

Then, I was talking of two features present at the same time. The first is nonnullable rerefence types, and the other is a bit of flow analysis that essentially gives a possible-null / surely-not-null state to a type:

S s = new S;
...
if (s != null) {
    // here s is essentially a S@
}


It avoids bugs like:

static int rose_rebuild_header(struct sk_buff *skb)
{
    ...
    if (!rose_route_frame(skbn, NULL)) {
        kfree_skb(skbn);
        stats->tx_errors++;
        return 1;
    }
    stats->tx_packets++;
    stats->tx_bytes += skbn->len;
    ...
}

The bug here is that in some cases skbn the code calls free on skbn, so at the end of the if{} yuou can't perform skbn->len in all cases. The type system has to denote this as a possible bug.

Just disallowing standard constructors is useful, but it's not enough.

With the exception of your first example, these require quite a lot of
plumbing in the compiler, and are thus not an alternative for D2 and,
I would say, unlikely for D3. The wrapper struct with a disabled default
constructor is close to possible in D2.

Like with AAs, the sugar for non-null can easily be implemented atop a
library solution, if the language is powerful enough. D is, except in
the case of type states or the like. Sure, I would love for D to have
a perfect type system, but I believe type state does not bring enough
goods to the table that it's worth implementing yet. Perhaps in D3.

Having a solution that works (your last example shows how it's possible
to have invalid pointers in non-null pointers, but not null-pointers),
is a lot better than hoping for something in the far future, and I have
yet to be made aware of any serious shortcomings of the solution with a
disabled default constructor.

--
Simen

Reply via email to