comp.lang.ada
 help / color / mirror / Atom feed
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.



  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