Karpov, Walter and D

bearophile bearophileHUGS at lycos.com
Mon Feb 4 15:13:19 PST 2013


Maybe I missed this in the D newsgroups, "The D language comes to 
help" by Andrey Karpov, Walter Bright. Andrey Karpov takes the 
ten most common bugs found by his static analysis tool, and asks 
Walter how D faces each one of those ten classes of problems. The 
resulting text is interesting:

http://www.viva64.com/en/b/0182/

Below some comments about the text.

------------------------

V547/V560:

>The unsigned<0 is usually a bug when it appears in top level 
>code. However, it can legitimately appear as a boundary case 
>inside of generic code.<

Then maybe it's possible to warn/error only about those 
comparisons that are _not_ inside a template.


>It can also be used in code that tests if a type is unsigned, as 
>in -(T)1<0. So I'm a bit uncomfortable in declaring it as always 
>wrong.<

I think the idiomatic way to do that in D is isSigned!T.

I think making that "-(T)1<0" useless is a small price to pay. (I 
have found some signedness-related bugs in my D code converting 
pieces of it to C and compiling it with GCC with its 
signed-unsigned mixing warnings).

- - - - - - - - - -

V595:

>I can't think of a case where this might be done legitimately. 
>But it does take some decent data flow analysis to be sure there 
>are no intervening modifications of buf.<

Is it worth doing that in D? Maybe the answer is positive.

(Rust (and other recent languages) avoids this problem in another 
way, using not nullabile pointers and introducing pattern 
matching).

- - - - - - - - - -

V501: it's a common bug. But I agree it's not easy to avoid it 
reliably in a compiler. That's why static analysis tools often 
return probabilities of errors, instead of just bad/good.

- - - - - - - - - -

V512/V579 and V557: some languages are able to avoid most of such 
problems using very refined type systems (dependent typing), but 
this adds a significant amount of complexity to both the language 
and to the programming. Maybe "liquid typing" is (will be) able 
to do it without an excessive amount of work for the programmer.

- - - - - - - - - -

V567/V610: I think there is some work left to do on this in D, 
but it's going to be fixed. Maybe there is no entry on that in 
Bugzilla.

- - - - - - - - - -

V597: this shows an example where a buffer is zeroed for security 
reasons, despite it's never used again by the user code (because 
it risks being used by external code).

>Being able to remove dead assignments is a very important 
>compiler optimization. They come up when instantiating generic 
>code and inlining functions, and as the consequence of 
>performing other optimizations. In C you should be able to force 
>the dead assignment to happen by declaring the target to be 
>volatile. The only way to force a dead assignment in D to happen 
>is to write it using inline assembler.<

Using assembly to clear a buffer is possible, but it's not so 
elegant. Maybe it's possible to add an annotation to D, like 
@keep, to stop the optimizer from removing something that is 
desired. Maybe this is not too much hard to implement.

- - - - - - - - - -

V519:

>Double assignment is a form of dead assignment, and my comment 
>on it is the same as for (7).<

This case is very different from case V597. This is more similar 
to V501. This is a matter of spotting duplicated assignments, 
because they are sometimes bugs.

- - - - - - - - - -

V576: D has enough features to avoid this kind of bug, but 
currently it's not doing it: I think Phobos should add functions 
like writecfln!"%d %f(10, 5.5), to catch at compile-time a wrong 
formatting string. Someone has already partially implemented 
those functions in D.

- - - - - - - - - -

V530:

>D does not have anything specific saying that a function's 
>return value must be used. In my experience, return values that 
>get ignored are often error codes, and D encourages the use of 
>exceptions to indicate errors rather than error codes.<

GCC-C has a function attribute to warn against not using a 
function result. Adding a @use_result to D is an option, and 
maybe it's not too much hard to implement. But I agree it's not a 
very common need in D.

In one case I have written:

arr.delete(5);

Instead of the correct:

arr = arr.delete(5);

Here not using the result of std.algorithm.delete is often a bug. 
But maybe it's not always a bug.

------------------------

On the other hand a significant part of the computing world seems 
to go in the opposite direction, embracing JavaScript more and 
more, and (despite TypeScript) mostly ignoring all the care about 
the enforcement of static correctness:

http://developers.slashdot.org/story/13/02/04/1819231/gnome-goes-javascript

Bye,
bearophile


More information about the Digitalmars-d-announce mailing list