www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - Karpov, Walter and D

reply "bearophile" <bearophileHUGS lycos.com> writes:
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
Feb 04 2013
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 2/4/2013 3:13 PM, bearophile wrote:
 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.
I can see the bug reports on such an inconsistency already. As a general note, putting idiomatic rules into the language like that makes it larger and significantly more difficult to comprehend.
Feb 04 2013
parent "deadalnix" <deadalnix gmail.com> writes:
On Monday, 4 February 2013 at 23:24:46 UTC, Walter Bright wrote:
 On 2/4/2013 3:13 PM, bearophile wrote:
 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.
I can see the bug reports on such an inconsistency already. As a general note, putting idiomatic rules into the language like that makes it larger and significantly more difficult to comprehend.
I have to concur. template and non template code must work the same way. This is a perfect job for static code analyzer however.
Feb 05 2013