www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Re: About some bugs

reply bearophile <bearophileHUGS lycos.com> writes:
Simen kjaeraas:

 bearophile <bearophileHUGS lycos.com> 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. Bye, bearophile
Jan 05 2011
next sibling parent reply "Simen kjaeraas" <simen.kjaras gmail.com> writes:
bearophile <bearophileHUGS lycos.com> wrote:

 Simen kjaeraas:

 bearophile <bearophileHUGS lycos.com> 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
Jan 05 2011
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
What I have written was meant for D3.

The example I've shown at the end is a bug found in the Linux kernel, they have
found many similar bugs, even in old code. Notnull types are usually not enough
to catch similar bugs.

The second part of my proposal was not a general typestate implementation, it's
specific, hard-coded, and only two or three states are present, for just
reference types, and only few built-in things change the state (if-then-else
branches, nullity assetions, nullable/notnull type annotations, and little
more).

In a language with gotos and asm your bit of flow analysis will produce some
false positives and some false negatives. This currently doesn't go well with D
Zen, but things may change.

Bye,
bearophile
Jan 05 2011
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
Simen kjaeraas:

 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.

Some "plumbing" is needed even for the first half of the proposal, to correctly manage partially initialized objects, it's explained here: http://research.microsoft.com/pubs/67461/non-null.pdf Some partial notes of mine on the topic are here: http://d.puremagic.com/issues/show_bug.cgi?id=4571 Bye, bearophile
Jan 05 2011
prev sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
bearophile <bearophileHUGS lycos.com> wrote:

 Simen kjaeraas:

 With the exception of your first example, these require quite a lot o=


 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 defa=


 constructor is close to possible in D2.

Some "plumbing" is needed even for the first half of the proposal, to =

 correctly manage partially initialized objects, it's explained here:
 http://research.microsoft.com/pubs/67461/non-null.pdf

 Some partial notes of mine on the topic are here:
 http://d.puremagic.com/issues/show_bug.cgi?id=3D4571

Now this is what I wanted to see. As D does not have C++'s initializatio= n lists, the problem of half-initialized fields may require flow analysis.= And yes, I remember this was discussed last time, but apparently I forgo= t. I see that this problem can also be thought of in the typestate paradigm= : a class is in the 'raw' state until constructors have finished running, and in this state the invariants of members are not guaranteed to hold. Hmm, the more I think about it, the more I believe you are right that typestates are Awesome=E2=84=A2, and should be included in D3. -- = Simen
Jan 05 2011