On Tue, 24 Nov 2009 15:00:11 -0500, Bartosz Milewski
<bartosz-nos...@relisoft.com> wrote:
It's hard to argue whether something is or isn't bug prone and how
severe the bugs could be. An experienced programmer knows all the
gotchas so he or she will never introduce such bugs. A more bug-prone
person will be afraid to speak up in public so as not to appear stupid
or be bullied away. It's only when the language goes into production
that the problems surface. Then an experienced programmer becomes part
of a group or not so experienced programmers and he or she starts seeing
how much the rests of the team is prone to certain bugs and how hard it
is to prevent or even detect them. That's why the best languages attempt
to turn as many errors as possible into hard bugs.
Yes, but there is a very fuzzy line between preventing all bugs and
preventing useful code. The safest most secure system is one that has no
inputs or outputs.
Non-deterministic behavior is a major source of soft bugs. A buggy
program might work correctly 99% of the time, introduce minor errors
0.9% of the time, and in 0.1% of the time lead to a disaster.
I will try to come up with some scenarios that would qualify for the
"100 Gotchas with D arrays" to provide more food for though. Consider
these little language puzzles.
Imagine you're reviewing this code written by a relative newbee:
char[] quote(char[] word) {
word.length += 2;
word[length-1] = '"';
for(int i = word.length-2; i > 0; --i)
word[i] = word[i - 1];
word[0] = '"';
return word;
}
void storeFoos(char[] buffer, string pattern, Container c)
{
char[] res = find(buffer, pattern);
c.store(quote(res[0..pattern.len]);
}
Is this buggy? If so, how and when will the bug manifest itself?
In my mind it is not buggy. If quote or storeFoos is not meant to be able
to molest the data, it should require a const(char)[]. If this was D1
code, I'd say it depends on the purpose of storeFoos, if storeFoos is
expecting to own the input buffer, it's not buggy. If it's not, then
storeFoos is buggy (in all cases). But we aren't talking about D1.
Or another story. An enthusiastic programmer comes to you with a very
clever rewrite of a function. This is the original:
T[] duplicate(T)(T[] src) {
static if (is(T == invariant))
return src.idup;
else
return src.dup;
}
This is his improved version:
T[] duplicate(T)(T[] src) {
T tmp = src[$-1];
src.length -= 1;
src ~= tmp;
return src;
}
No need for static if! The extension is bound to re-allocate because of
stomping rules. Will this always work, or is there a gotcha?
He forgot to check for length 0.
Also, you are a bit generous on your use of 'clever' :)
-Steve