From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=BAYES_00,INVALID_DATE autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,a8985ede8fe3d111 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 1994-10-04 04:02:30 PST Newsgroups: comp.lang.ada Path: bga.com!news.sprintlink.net!howland.reston.ans.net!usc!elroy.jpl.nasa.gov!decwrl!netcomsv!ix.netcom.com!netcom.com!cpp From: cpp@netcom.com (Robin Rowe) Subject: Ada compared to C++ Message-ID: Cc: Schonberg@cs.nyu.edu Organization: NETCOM On-line Communication Services (408 261-4700 guest) References: <36h4pc$9dd@starbase.neosoft.com> <36msgr$qq2@starbase.neosoft.com> Date: Tue, 4 Oct 1994 07:21:49 GMT Date: 1994-10-04T07:21:49+00:00 List-Id: ========================================================== 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 array(SIZE); // An array container. for(int i=0;i> 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<> 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<> 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.