comp.lang.ada
 help / color / mirror / Atom feed
From: rlk@rational.com (Bob Kitzberger)
Subject: Re: Ada compared to C++
Date: 5 Oct 1994 06:44:11 GMT
Date: 1994-10-05T06:44:11+00:00	[thread overview]
Message-ID: <36thvr$m3d@rational.rational.com> (raw)
In-Reply-To: cppCx50GD.G0y@netcom.com

Robin Rowe (cpp@netcom.com) wrote:

> BUILDING SYSTEMS WITH OUT-OF-DATE COMPONENTS
> --------------------------------------------
> 
> ES: <<...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. 

ES was being a bit extreme about this.  In all of the Ada environments
I've used, you can indeed use prior versions of units to build an
executable (but not out-of-date components).  The key point here is
that when you build an Ada program, the transitive closure of the
main program is examined for out of date components, and those
components (or parts of components -- statements, etc.) are recompiled
before linking the executable.  The _domain_ that defines the
transitive closure may specify to use personal libraries, e.g., in 
computing parts of that closure.  

Typically, you must go out of your way, with Ada environments, to 
build an inconsistent application (i.e. one using unintended versions
of components).    I would hope this is the same case in C++ 
development, though I personally find the "make" family of tools
to be an incredible drag (and yes, I know them reasonably well).
"an incredible drag" isn't much of a technical argument, I know ;-)


> 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.

Availability of C and C++ development environments on a multitude
of environments is not the same thing as portability of applications
written in C or C++ (as an aside, there are many Ada development
environments available, from lowly PCs to Crays and everywhere in 
between).  

The problem with portability in C and C++ is that there is a plethora
of implementation inconsistencies (K&R vs. ANSI C, C++ with templates,
C++ without templates, C++ with namespace, C++ without namespace etc.)
To remain truly portable implies adhering to the least common
demoniator, K&R (yes, an extreme conclusion not to be taken seriously).
With C++ standardization, this will become much less of a problem.

My suspicion, though, is that the real problem for C++ or Ada viz-a-viz
portability is the use of external frameworks -- class libraries, GUI
libraries, OS services, thread libraries, etc. that are not necessarily
portable from one platform to another.  Ada has a _slight_ advantage
here, in that concurrency is provided in the language, and so at least a
subset of concurrent applications are portable from one platform to
another (I have developed concurrent embedded systems components
entirely on the host, with minimal tuning on the target -- an everyday
occurence in Ada).  On the other hand, C++ has a big advantage insofar
as most APIs are defined in C, and thus trivially called from C++. 
Ada requires either the existence of a binding to the service
(e.g. POSIX/Ada) or writing "pragma Interface" skins over the API.
I believe there are tools to automate this process (gadzooks!  I work
for a tool vendor; need to get cracking on it!)

> 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.

How can this be applied outside of iterators?  I agree, though, that
the real answer is to use array templates.

> 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? 

It's very difficult to overrun an array (I have yet to write code that
did this, in years of Ada work) but if this happens, then a
predefined exception is raised.

> What does it do if exceptions are turned off?

Undefined (caveat exceptor ;-)

> <<...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.

r.e. C++ checks types on indices -- a question.  I thought that array
indices can only be integers (if my quick scan of the C++ RM is
correct).  So what does it mean to check types of array indices in C++?
An example?

In any event, the more pervasive problem is the lack of range
checking on indices (or any scalars, for that matter) in C++.  In Ada:

    type Array_Range is range 1..MAX_ELEMENTS;
    type Elements is array(Array_Range) of Element;

You cannot use anything except an object of Array_Range to index
into Elements, without going through gyrations.  The compiler will
check types on the index, and complain loudly of violations.  To 
perform the equivalent in C++ requires creation of a new class (or
subclass, if you have an appropriate base class handy).  

The more mundate situation is simple range constraints on scalars:

    Precision: constant := 0.1;
    type Degree_Measure is delta Precision range 0.0 .. 360.0;
    type Lattitude is new Degree_Measure;
    type Longitude is new Degree_Measure;

Of course, type and range checking are performed.  Again, to perform the
same thing in C++ requires creation of a new class (probably not a bad
idea, that, but do all (most?) C++ developers honestly create a new
class to handle range constraints on simple scalars? 

> EXCEPTIONS
> ----------
>
> Testing exceptions is often not feasible.

Can you expand on that?    This is more than a rhetorical
request: I develop testing tools, and we do support testing (or plan
on it ;-) of exceptions in most ways that I can conceive of.

> 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.

The more general problem, IMHO, is that inline accessors break 
encapsulation and violate information hiding, by exposing
class internals at the interface level.  The need to declare
all private members in the class definition is a bit distasteful
as well (yes, the compiler still enforces the encapsulation, but
the internals are still visible; perhaps this is just a pet peeve
of mine).   Anyone can see your privates, but only your friends
can access them ;-)

> 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.

Yes, both languages took opposite choices in the tradeoff: portability 
vs. flexibility.  As more applications in C++ start using thread
libraries, and running into portability issues, re-entrant code issues,
etc. it may be that concurrency is the next feature to be added to
C++ ;-)  

> 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.

The ES paper was written several years ago, when templates were hot
off the press.  You've got to give ES a break on these points ;-)

> 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.

Not sure that I agree that C++ is more mathematical.  e.g.:

    X := X + 1;     -- Ada  
    if ( x = x+1)   -- "

    x++;            // C++
    x = x + 1;      // "
    ++x;            // "
    if (x == x+1)   // "
    x += 1          // "
    
Since Ada uses ":=" for assignment, it is clearly not the same as the
mathematical equation "x = x + 1".  But the C++ version use the same
notation as the mathematical equation, but is bogus: obviously x cannot
equal x + 1.  Hence the ever-present "=" vs. "==" mistakes (albeit
catchable by lint, if you choose to run it and ignore those cases
where it whines about non-problem areas).

The pre-increment and post-increment operators aren't very
'mathematical', either.  As for "op=" operators, I'm a bit fond of them ;-)

But perhaps you were thinking about some other examples, not 
necessarily the trivial examples I've shown that shed a positive
light on Ada ;-)  Seriously, post an example, and I'll write
an Ada equivalent.  Try for an example that C++ is particularly good
at expressing in its syntax.

One nice thing about Ada's syntax is the ability to self-document
code, by being verbose when needed, and (somewhat) terse when 
needed.  For example, consider the following:

    procedure Append(Source : in Object; Target : in out Object);

To call this function, I could write:

    Append( X, Y);

...but if Append's definition isn't close at hand, it isn't at all
obvious what this means... is X appended to Y, or visa versa?  To
self-document, I would write:

   Append( Source => X, Target => Y );

With a decent LSE, it's not much typing, either.

> Here's how I read a piece of C++ code:

...yes, as do I.  The simple examples are a bit misleading, though.
What is more confusing are if statements containing assignments, e.g.
and other side effects of not having a predefined boolean type.

    if(object= new_object())
        Frobozz;

This example bring up another danger: using conditionals without 
brackets.  Further maintenance of the code could easily produce the
following error:

    if(object= new_object())
        Frobozz;
        Blat;

...where Blat is executed regardless of the conditional.  Yes, coding
conventions could "solve" this problem -- but there are so many cases
where coding conventions are relied on to mitigate danger zones in the
syntax ("=" vs. "==", etc.) that a book has been written on the topic
("Writing Solid Code" or somesuch, by MicroSoft press).

Is this a readability problem?  Certainly... since during maintenance
the code was obviously misread.  And yes, these are C issues, but they
are inherited by C++.

> OBFUSCATED CODE
> ---------------
>
> 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?". 

Agreed (modulo the need for lint in the first place ;-)

> 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. 

The tendency isn't limited to the net -- merely to those that take
these things seriously ;-)   Re-reading my response, I see obvious
tinges of evangelism (and in ES' paper, and in your response).
Ah well.

    .Bob.





--
Bob Kitzberger	        +1 (916) 274-3075	        rlk@rational.com
Rational Software Corp., 10565 Brunswick Rd. #11, Grass Valley, CA 95945



  reply	other threads:[~1994-10-05  6:44 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       ` Ada compared to C++ Robin Rowe
1994-10-05  6:44         ` Bob Kitzberger [this message]
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