David Kastrup wrote:
Again, C won't keep you from shooting yourself in the foot.
Right, it won't. A good systems language should do what it can to
prevent the programmer from *inadvertently* shooting himself in the
foot, while allowing him to *deliberately* shoot himself in the foot.
In the example loop, the cases I pointed out were ones where, if one
changes part of the code (such as the array dimension, or the array
type, etc.), then there are multiple places in the source that must be
updated to reflect it. The reality of human programmers is we update one
or two places, and overlook the third place, and we now have a bug.
Saying that one should just be a better programmer and not make such
mistakes is a pipe dream.
Ideally, each facet of the design of the code should have a single point
where it can be changed, and then all dependencies on that design should
be automatically updated. That way, nothing gets overlooked. Doing this
in C, such as using a #define for the array dimension, involves extra work.
It's a truism that if it involves extra work, then it often gets omitted.
Doesn't "A design is perfect not when there is no longer anything you
can add to it, but if there is no longer anything you can take away."
apply here? Going from:
void foo(int array[10])
{
for (int i = 0; i < 10; i++)
{ int value = array[i];
... do something ...
}
}
to:
void foo(int[] array)
{
foreach (value; array)
{
... do something ...
}
}
takes a lot of frankly unnecessary things away, each of which is a
potential source of error when maintaining the code.
No, because programmers get things wrong.
Exactly. That goes back to my point that a good language should help
prevent inadvertent errors, while still allowing deliberate choices. D
approaches this by making the correct approach essentially be the one
with minimal typing effort. To deliberately shoot yourself in the foot
usually requires extra typing. For our loop example, we can still write
the C style loop (with all its potential problems) in D, but it requires
extra effort to put in those potential problems. The easier, simpler way
doesn't have the problems.
(The issue I have with C++'s fixes to various problems is they require
extra typing (like the loop example), so guess what, people being people
tend to not use them. This results in endless attempts to try and push
C++ programmers into using the more verbose forms, a strategy I suspect
will be ultimately futile.)
You can tell C compilers to
check all array accesses, but that is a performance issue.
Runtime checking of arrays in D is a performance issue too, so it is
selectable via a command line switch. But more importantly,
1) Static type checking of fixed size arrays works, so errors can be
caught at compile time.
2) For dynamically sized arrays, the dimension of the array is carried
with the array, so loops automatically loop the correct number of times.
No runtime check is necessary, and it's easier for the code reviewer to
visually check the code for correctness.
------
Walter Bright
http://www.digitalmars.com C, C++, D programming language compilers
http://www.astoriaseminar.com Extraordinary C++
-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html