From: cpp@netcom.com (Robin Rowe)
Cc: Schonberg@cs.nyu.edu
Subject: Ada compared to C++
Date: Tue, 4 Oct 1994 07:21:49 GMT
Date: 1994-10-04T07:21:49+00:00 [thread overview]
Message-ID: <cppCx50GD.G0y@netcom.com> (raw)
In-Reply-To: 36msgr$qq2@starbase.neosoft.com
==========================================================
Response to Edmond Schonberg's "CONTRASTS: Ada 9X and C++"
==========================================================
by Robin Rowe
Rowe Technology
cpp@netcom.com
Posted to comp.lang.ada (10-3-94)
cc: Schonberg@cs.nyu.edu
Schonberg's paper can be retrieved as:
9x-cplus.txt under /public/ada9x/reports/misc
ftp ajpo.sei.cmu.edu
INTRODUCTION
------------
Before I begin, I want to make two things clear. One, that I intend
no disrespect to the author of the original paper, and two, that I
am an expert in C++ but not in Ada. Edmond Schonberg chose a
challenging task in comparing the safety and reliability of Ada and
C++. It is very difficult to be neutral when comparing two
languages, and almost impossible to be proficient enough in both
languages to draw valid comparisons. Few engineers can write the
equivalent code in two dissimilar languages.
Reliability and engineering in C++ hold special interest for me. I
have recently given talks on this topic at Object Expo in NYC and
the Symantec Developers Conference in Monterey. It is also what I
teach as a C++ trainer. My background includes teaching Intermediate
C++ for a year at the University of Washington.
Schonberg says:
<< The comparison of programming languages is in part a subjective
affair....>>
This is true. However, I think the ES paper suffers from being too
hypothetical in nature. It contains no realistic C++ code examples.
Many assertions were made with so little basis that I couldn't
imagine how the author's point would translate into an actual
design. Anyone can prove anything in the abstract. Not having
concrete examples was the hardest part in responding to the ES
paper. If the topic is which software language can better support
software safety and reliability, then I think it is incumbent upon
the author to actually show some safe and unsafe code so the danger
can be seen clearly.
BUILDING SYSTEMS WITH OUT-OF-DATE COMPONENTS
--------------------------------------------
<<...the first guarantee of reliability is that the Ada system
itself will not let you build a system with out-of-date
components.>>
In C++, proliferation of components seems to be a much greater
problem than building with out-of-date components. It's not unusal
to have developers deliberately using out of date libraries because
the new ones don't work yet or aren't tested yet. ES admits that
'make' can handle the task of keeping components up to date, and
neglects to mention that C++ shops routinely use version control
software to keep projects up to date. It would be nice to have these
tools built into the compiler (and that is the way things are moving
in C++), but the versioning problem extends well beyond the
language, or even the tools.
PORTABILITY
-----------
ES contends that portability is difficult to achieve in C++. C is
the most ported language around, and C++ is ported a lot. C++
is not just a Unix tool, as some contend. More MS-DOS C++ compilers
have been shipped than for any other platform. Commercial DOS and
Windows programs written in C or C++ include WordPerfect, Lotus
1-2-3, Paradox, Word, Excel and dBase, just to name a few. Lotus
1-2-3 was even rewritten from scratch in C to gain portability. I
think this non-portability argument can be dismissed.
ARRAYS
------
ES doesn't seem to want to talk about array templates in C++. All
of his array issues apply just to C-style arrays. A C++ array
template can check indexing operations, do array assignment, use
indices of other types, handle sparse arrays, and whatever else you
can come up with.
<< Given that indices out of bounds are the most common type of
run-time error, this makes the use of arrays in C++ inherently less
safe than in Ada.>>
This is a good point. C-style arrays are often misused in C++.
However, there is a common idiom to avoid running off the end of a
C-style array: use asymmetrical bounds. The 'i' in this code won't
fall off the end of the array:
enum {SIZE=1000}; // A constant called SIZE.
int array[SIZE]; // An array of integers.
for(int i=0;i<SIZE;i++) // Arrays start at 0, end just before
SIZE.
{ array[i]=i; // Set each element equal to its offset.
}
array[SIZE]=0; // Memory corrupted. Unchecked except by test.
Here it is using an array template:
enum {SIZE=1000};
Array<int> array(SIZE); // An array container.
for(int i=0;i<SIZE;i++)
{ array[i]=i;
}
array[SIZE]=0; // Wrong, but handled by template.
The deeper question is, what does it mean that the programmer made
an error in accessing the array? Should the program abort, continue,
make the array bigger, throw the problem back to the caller, log the
error to a file, what?
What does Ada do when an array is overrun? What does it do if
exceptions are turned off?
<<...one cannot define an array over an enumerated type, and there
is never any type checking on indices.>>
C++ can have an array template over an enumerated type, but it is
inconvenient. C++ always type checks on indices. It is bounds
checking that is not done on C-style arrays.
EXCEPTIONS
----------
<< Unfortunately, the proper implementation of the [Array] class
requires exceptions, a feature which has only recently been
introduced into C++ and which is not widely (nor consistently)
implemented yet.>>
No, exceptions are not required. As in Ada, using exceptions is
actually not a very good idea for systems demanding high
reliability. The reason is that exceptions want to terminate the
program. Only if the programmer manages to catch the exception is
abort avoided. Testing exceptions is often not feasible.
With an array template, the programmer can do something like this
(without exceptions):
array[SIZE]=0; // Wrong, but handled by template.
if(array.HasError())
{ cerr<<"Tell the clumsy programmer to stay inside array";
} // cerr is console error message.
Exceptions are available in many C++ compilers now, and will be
commonplace in C++ compilers within a few months. All the major C++
compiler vendors now have them in beta.
Isn't it true that Ada exceptions are typically turned off for
safety-critical software designs?
<< We should also remark that compilers make a big effort to
optimize the use of built-in arrays, because they are the basic
structure of many compute-intensive programs. Compilers are much
less likely to treat user-defined arrays with the same care....>>
Without examples, it's impossible to judge where this may be
relevant.
OBJECT-ORIENTED PROGRAMMING
---------------------------
<< Object-oriented programming and design (OOP) has become the
buzzword of the decade. Behind the obvious enthusiasm of the
software community there lies the correct perception that OOP
simplifies the design and construction of software systems. The
basic reason is ease of reuse. >>
No, the important reason is encapsulation. It is through
encapsulation that objects maintain their integrity. Reuse is good,
too. But, you're missing the point if reuse is the primary goal of
your design philosophy. Encapsulation makes it possible for objects
to resist failure.
Does Ada support the concept of private, protected, and public
class members?
<< But in fact the usefulness of OOP....lies in the combination of
inheritance, specialization by extension, and dynamic dispatching.
The gain is in the amount of code that one does not have to write,
simply because one can obtain it by inheritance from the previously
defined software component. >>
The features supported by an object-oriented programming language
are polymorphism, inheritance, and encapsulation. (See Grady Booch
if you don't believe me.) How does Ada implement each of these? May
I see some compilable code examples that do something useful?
Inheritance for reuse is often an abuse, at least in C++, because
derived classes may invalidate tested base classes through protected
member access. Also, any inherited class is interchangable with its
base class in C++ (through a reference or pointer). Making truly
interchangable parts is not that easy.
Containment is generally a much better form of reuse in C++ and
doesn't subvert the type system. In C++ a class is a definition of
how an object works, not the actual object. I've heard Ada doesn't
work this way. How does Ada support objects containing other
objects?
METHODS AND FUNCTIONS
---------------------
<<...the notion of class in C++ derives from that of structure, and
suggests that subprograms that apply to objects of a class are in
some sense part of those objects (class members). >>
No, not everything in C++ is a method. You just use it where makes
sense.
BCD bcd=10; // Binary coded decimal object named 'bcd'.
int x=11; // An integer named x.
cout<<max(bcd,x); // This way is typical, global function.
cout<<bcd.max(x); // Legal but ugly method call.
cout<<x.max(bcd); // Illegal. Built-in type can't have methods.
// cout is console output, in this case '11'.
ENCAPSULATION
-------------
<< In our experience, it is seldom useful to think of the
operations as being part of a value (unless they are entries in a
task). The Ada 9X model provides the benefits of OOPS without this
somewhat muddled notion of object. >>
This is contrary to common sense and OOP practice. Asking an object
to perform an action on itself instead of twiddling with its
internals yourself is the foundation of OOP. It is this
encapsulation that makes for reliable objects. A C++ object can
resist doing something wrong.
<< Note also that C++ classes are the only encapsulation mechanism
in the language (if one excludes the use of files as modules), and
thus they also play the role that packages play in Ada. This dual
role is better served with two separate notions. >>
C++ has added namespaces to deal with this issue.
<< The Ada 9X model also provides a more natural description of
binary operations....In the C++ model the member function has an
implicit first parameter:
class parent {
...
parent merge(parent)
...
}
class child: public parent { ...
>>
This example is so sketchy that it is impossible to see what its
usefulness could be. There are at least two errors in these four
lines of code. (The type passed to merge should be a reference to a
parent, not a copy, and the semi-colon is missing at the end of the
class declaration.) Without some idea of what useful purpose this
code could have, no further comment is possible. What's the point?
FRIENDS
-------
<< The notion of friend functions and friend classes is one of the
more controversial aspects of C++. Its defenders correctly point out
that the built-in privacy of class members that are not explicitly
declared public means that it is well-nigh impossible to write
efficient code that makes use of two distinct classes A and B....>>
No, inline accessor functions are generally just as efficient as
direct public access. This issue is not a general problem, but a
special case.
<< This is often unacceptable (the canonical example is
vector-matrix multiplication, when each is defined as a separate
class, which forces a large number of redundant index checks in the
code). >>
C++ matrices are often made up from two classes so that the [][]
notation can be used:
Matrix m(10,10); // 10x10 matrix.
m[5][5]=7; // Set a matrix element to 7.
// 2nd hidden object manipulates 2nd [].
If you aren't attached to this notation, you can instead do this:
Matrix m(10,10);
m(5,5)=7; // No 2nd bracket. No need for hidden object.
In Ada, if I'm not mistaken, friendship is taken, not granted.
Isn't this dangerous?
ITERATORS
---------
Using friends as an efficiency trick is rarely called for. A more
typical use of friend is for iterators. The friend mechanism allows
splitting a class into a one to many relationship. Making an
iterator a friend instead of a member of a container makes it
convenient to have multiple cursors into the same object. A typical
example is smart pointers into an array. How does Ada handle
iterators? How does Ada support containers?
REAL-TIME
---------
<< There are as yet no winning proposals for tasking facilities in
C++, and no hint of notions of real-time and scheduling tools. In
this area C++ is a non-starter, even compared with Ada83. >>
Bjarne Stroustrup (the designer of C++) feels that real-time is
better supported through libraries in C++ than by language
extension. Rather than make this a least common denominator type of
feature, it is up to each implementation to do the best it can. This
approach was used successfully with i/o and seems reasonable to most
C++ programmers.
TEMPLATES
---------
<< The designer of C++ has recognized the need for a more
disciplined parametrization mechanism, and the latest version of
the language describes templates, a facility that is close in spirit
to Ada generics. >>
Templates have been around for a while in C++, hardly one of the
latest features. They are in the ARM (the Annotated Reference Manual,
published in 1990). The most popular C++ compiler (Borland) has had
them for years.
<< Ada 9X has an even richer set of parametrization mechanisms than
Ada. In Ada 9X it is possible to specify generic derived types
(where the actual is any member of the class of the generic type)
and generic formal packages (where the actual is any instantiation
of the generic formal package). This later form of parametrization
is more powerful than what is available in C++, and is akin to the
use of functions and signatures in ML. Both in terms of
expressiveness and clarity Ada 9X has a clear advantage over C++
here. >>
You will have to show some code examples for me to buy any of this.
Of what use is this "more powerful" parameterization?
MULTIPLE INHERITANCE
--------------------
<< It might be argued that the multiple inheritance model of the
current version of C++ is definitely superior to what is proposed
for Ada 9X. This is a most minor point....>>
Granted on both counts.
READABILITY
-----------
<< Ada programs read well....In contrast, C and C++ emphasize ease
of writing rather than ease of reading. Thus a greater use of
operators, of terser notations (the conditional expression, for
example) and an absence of keywords (most noticeably in
declarations). This makes C++ programs harder to transmit and to
maintain. >>
This is quite an amazing assertion to make without giving any code
examples! C++ code does look a lot more mathematical than COBOL, a
language designed to avoid this notation. Is being more like COBOL
an advantage? Some people (engineers, for instance) find a
mathematical notation much more readible and precise than the
equivalent English sentences.
The ternary operator '?' is rarely used except in return
statements. It's no big deal.
<< In fact, those [Ada] keywords act as natural punctuation marks,
and make program reading more natural: a begin-end bracketing is
more natural-sounding than {..}. >>
Here's how I read a piece of C++ code:
if(!object) // "If not object [then]"
{ cerr<<object.ErrorMsg(); // "output object's error
} // message,"
else // "else"
{ object++; // "increment object."
}
So what's unnatural about this? Sounds like English to me.
OBFUSCATED CODE
---------------
<<...it is clear that C and C++ programmers enjoy enormously the
game of "guess what this computes?". The question would not be fun
if the answer were not in same way unexpected! ....In contrast, this
form of entertainment is completely missing from the Ada culture.
Ada code does what it says, plainly. >>
This is like saying demolition derbies prove all cars to be unsafe.
There are a large number of hackers in C, and now C++. I'm sure
these individuals could write code just as perverse in Ada if it was
popular enough that others would get the joke. Almost every
indictment of C or C++ that I've seen includes some reference to the
Obfuscated Code Contest, which is sort of a Rube Goldberg contest
for C. It doesn't prove anything except that people can write bad
code if they try. Like Freud said, "Sometimes a cigar is just a
cigar."
Along similar lines, I think most programmers are familiar with the
pc-lint ads in the programming magazines. The ads present, for
instance, "C/C++ Bug #525" where the reader is challenged to
discover why some piece of horrendously bad C code doesn't work.
Students are particularly intrigued by this sort of thing, mainly
because they can't see the answer. For 99% of the time the correct
response is, "Who cares?". The code is so poorly designed there is no
point in correcting its defects. Real code like this is sure to have
logic errors, too.
STANDARDIZATION
---------------
<< To compare Ada 9X and C++ is not easy, if for no other reason
than C++ is a language in flux for which no stable definition
exists, no approved standard reference, and no translator validation
suite. A glance at the list of additions to the language since
version 2.0 (see [S91]) is sufficient to realize that active
language design is still going on. >>
The ANSI committee recently completed the feature set of C++ and is
now preparing the draft standard proposal. It's no longer in flux.
I'd like to know more about the Ada translator validation suite.
Exactly what does it validate?
CONCLUSION
----------
Rather than being black-and-white, it's more likely that Ada is
better in some areas of software engineering and C++ is superior in
others. The Schonberg paper doesn't present enough information to
draw informed conclusions about which those areas are.
For those who chose to follow up, I hope we can stick to software
engineering issues and somehow avoid the unfortunate tendency on the
net of language evangelism. Surely Ada and C++ can each stand on
their own merit. Perhaps together we can discover something new
about how Ada and C++ can best be used, and about software
engineering in general.
Robin
--
-----
Robin Rowe cpp@netcom.com 408-375-9449 Monterey, CA
Rowe Technology C++ training, consulting, and users groups.
next prev parent reply other threads:[~1994-10-04 7:21 UTC|newest]
Thread overview: 70+ messages / expand[flat|nested] mbox.gz Atom feed top
1994-09-29 20:08 Is Ada the future? [was: Is C++ the future?] John DiCamillo
1994-09-30 13:45 ` David Weller
1994-10-01 21:40 ` John DiCamillo
1994-10-03 9:53 ` Robert I. Eachus
1994-10-03 20:41 ` John DiCamillo
1994-10-04 8:41 ` Robb Nebbe
[not found] ` <85C825A689A@annwfn.com>
1994-10-13 14:40 ` John Volan
1994-10-13 21:14 ` Matt Kennel
1994-10-14 0:37 ` Robert Dewar
1994-10-14 10:16 ` Robb Nebbe
1994-10-14 20:43 ` Bob Duff
1994-10-13 22:01 ` Val Kartchner
1994-10-14 1:38 ` Robert Dewar
1994-10-14 9:31 ` Robb Nebbe
1994-10-14 16:16 ` Child packages [nn,pedo,incest,cons] Robert Firth
1994-10-14 17:13 ` Robert I. Eachus
1994-10-17 8:18 ` Robb Nebbe
1994-10-17 11:52 ` Robert I. Eachus
1994-10-17 21:54 ` Bob Duff
1994-10-18 10:30 ` Child packages Robb Nebbe
1994-10-18 9:37 ` Robert I. Eachus
1994-10-18 19:09 ` Robert Dewar
1994-10-19 11:03 ` Robert I. Eachus
1994-10-19 16:24 ` Norman H. Cohen
1994-10-19 23:13 ` Robert Dewar
1994-10-20 14:06 ` Norman H. Cohen
1994-10-20 11:09 ` Robert I. Eachus
1994-10-20 19:02 ` Benjamin Ketcham
1994-10-20 17:08 ` Robert I. Eachus
1994-10-20 16:37 ` Bob Duff
1994-10-20 16:40 ` Bob Duff
1994-10-21 14:02 ` Mark Biggar, 5172
1994-10-21 8:48 ` Robb Nebbe
1994-10-19 18:54 ` Robert Dewar
1994-10-20 0:27 ` Matt Kennel
1994-10-20 8:21 ` Magnus Kempe
1994-10-20 13:52 ` John Volan
1994-10-19 16:19 ` Norman H. Cohen
1994-10-04 14:44 ` Is Ada the future? [was: Is C++ the future?] Robert Dewar
1994-10-04 15:53 ` Richard Kenner
[not found] ` <36h4pc$9dd@starbase.neosoft.com>
1994-09-30 20:15 ` Benjamin Ketcham
1994-10-02 16:30 ` Robin Rowe
1994-10-02 18:00 ` David Weller
1994-10-03 15:55 ` Netspeak: What is "trolling"? Norman H. Cohen
1994-10-03 17:04 ` Kenneth Aubey 913-4481
1994-10-03 21:06 ` Is Ada the future? [was: Is C++ the future?] John DiCamillo
1994-10-04 0:29 ` David Weller
1994-10-04 17:42 ` John DiCamillo
1994-10-05 8:18 ` Magnus Kempe
1994-10-05 13:49 ` Tucker Taft
[not found] ` <36q7m5$4ef@starbase.neosoft.com>
1994-10-04 17:55 ` Robin Rowe
1994-10-04 22:42 ` Tucker Taft
1994-10-03 9:22 ` Andrew Lees
1994-10-03 21:31 ` John DiCamillo
1994-10-04 23:29 ` John DiCamillo
1994-10-05 3:52 ` Robin Rowe
1994-10-05 13:15 ` Robert Dewar
1994-10-05 13:54 ` David Weller
[not found] ` <36uhnl$4c1@gnat.cs.nyu.edu>
[not found] ` <37dp17$gp6@goanna.cs.rmit.oz.au>
1994-10-11 13:37 ` Robert Dewar
1994-10-19 11:24 ` Stephen J Bevan
1994-10-19 15:51 ` Robert Dewar
1994-10-25 12:21 ` Stephen J Bevan
1994-10-05 17:08 ` Ted Dennison
[not found] ` <36msgr$qq2@starbase.neosoft.com>
1994-10-04 7:21 ` Robin Rowe [this message]
1994-10-05 6:44 ` Ada compared to C++ Bob Kitzberger
1994-10-05 12:02 ` Robert Dewar
1994-10-05 18:20 ` Bob Kitzberger
1994-10-05 8:44 ` Magnus Kempe
1994-10-05 19:55 ` David Weller
[not found] ` <1994Oct6.133002.1@rapnet.sanders.lockheed.com>
1994-10-16 3:30 ` Mark S. Hathaway
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox