473,461 Members | 1,980 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Teaching new tricks to an old dog (C++ -->Ada)

I 'm following various posting in "comp.lang.ada, comp.lang.c++ ,
comp.realtime, comp.software-eng" groups regarding selection of a
programming language of C, C++ or Ada for safety critical real-time
applications. The majority of expert/people recommend Ada for safety
critical real-time applications. I've many years of experience in C/C++ (and
Delphi) but no Ada knowledge.

May I ask if it is too difficult to move from C/C++ to Ada?
What is the best way of learning Ada for a C/C++ programmer?

Jul 23 '05
822 28874
Pascal Obry wrote:
Ioannis Vranos <iv*@remove.this.grad.com> writes:

arrays. The [0, +] style maps closely what is happening in the machine.

Certainly. But the Ada model can maps more closely to the domain problem.
And this is an important point. We are not writting software for the machine
but to solve problems. Most of the time you just don't care how such data will
be handled by the machine (i.e. how the compiler will generate the code).

C++ maps on both. However I guess Ada maps on both too since it is a
systems programming language. :-)
Now may you explain how the ability to use negative subranges for built
in array indices makes Ada better for any domain problem?

--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 23 '05 #551

Ioannis Vranos <iv*@remove.this.grad.com> writes:
Now may you explain how the ability to use negative subranges for built in
array indices makes Ada better for any domain problem?


For a domain problem where you have to create an area centered on (0,0)
for example. What about a vector representing altitude, the sub-zero values
being under the water. Just some examples, I bet you'll be able to think about
lot more :)

Pascal.

--

--|------------------------------------------------------
--| Pascal Obry Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--| http://www.obry.org
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595
Jul 23 '05 #552
Ioannis Vranos wrote:
Georg Bauhaus wrote:
I forgot to say here that the cost of map's operator[] is O(log(n))
which is fairly cheap for large amount of data.


compare O(log(n)) to O(1) where n is 1, 1000, 1_000_000.
Make this access a part of an inner loop.


If you do the maths, you will see that log(10^6) isn't that large.


Yeah, right. Binary searches are not much slower. Only about 10 or 20
times. Seem, you just rendered hashing algorithms obsolete.
Vinzent.

--
worst case: The wrong assumption there actually is one.
Jul 23 '05 #553
Pascal Obry wrote:
For a domain problem where you have to create an area centered on (0,0)
for example. What about a vector representing altitude, the sub-zero values
being under the water. Just some examples, I bet you'll be able to think about
lot more :)

I think an associative container like map fits better to this. What do
you do in Ada if you want to associate product names with prices, in the
style
productlist["something"]= 71.2;
or a name with a number (string with string) in an address book
application for example?
namelist["Obry Pascal"]="321-45563";
Also may you tell me if that famous compile-time boundary checking
applies (can be used) to user-defined containers too?

--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 23 '05 #554

Ioannis Vranos <iv*@remove.this.grad.com> writes:
I think an associative container like map fits better to this. What do you do
in Ada if you want to associate product names with prices, in the style
productlist["something"]= 71.2;
or a name with a number (string with string) in an address book application
for example?
namelist["Obry Pascal"]="321-45563";
We use a map, using the Ada.Containers STL like library.
Also may you tell me if that famous compile-time boundary checking applies
(can be used) to user-defined containers too?


What do you mean by that ? You want to restric a map index ?

Pascal.

--

--|------------------------------------------------------
--| Pascal Obry Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--| http://www.obry.org
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595
Jul 23 '05 #555
Pascal Obry wrote:
Also may you tell me if that famous compile-time boundary checking applies
(can be used) to user-defined containers too?

What do you mean by that ? You want to restric a map index ?


In the "STL like" library do you have something like valarray or vector?

--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 23 '05 #556
Ioannis Vranos wrote:
Georg Bauhaus wrote:
I forgot to say here that the cost of map's operator[] is O(log(n))
which is fairly cheap for large amount of data.


compare O(log(n)) to O(1) where n is 1, 1000, 1_000_000.
Make this access a part of an inner loop.


If you do the maths, you will see that log(10^6) isn't that large.


Compare log(10^6) to 1.

I can't see how O(log(n)) isn't huge when compared to
O(1), in an inner loop for containers of size 10^6.
Georg
Jul 23 '05 #557
Ioannis Vranos wrote:
What do
you do in Ada if you want to associate product names with prices, in the
style


Once again you are trying to escape the problem...
We are not discussing the value of a map. We are not
debating it either.

A map *is* most valuable. A map is *not* a vector.
Sometimes you *need* a vector. A vector is *not* a convenient
replacement for a map in C++.

And of course there are maps for Ada, but this is OT.
Jul 23 '05 #558
Georg Bauhaus wrote:
Compare log(10^6) to 1.

I can't see how O(log(n)) isn't huge when compared to
O(1), in an inner loop for containers of size 10^6.


OK, but besides the fact that only explicit entries in map occupy space,
and the rest keys return 0, which means that the search and counting of
a value is faster than an array in case that no the entire range is
under use, there are also third-party hashed containers, including
hashed maps.

Also, as I said it is not difficult to define an array that takes
arbitrary signed ranges, but this does not make much sense in C++.
In other words, the direct equivalent of your array is probably
valarray/vector, ignoring the signed ranges.
BTW, the compile-time boundary checks you have been mentioning, sounds
like they are restricted to built-in arrays, which means is not of much use.
Also the lack of a "STL like" library in Ada until now probably sounds
like that Ada lacks much of the high-level abstraction that C++ provides.

--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 23 '05 #559
Georg Bauhaus wrote:
Once again you are trying to escape the problem...
We are not discussing the value of a map. We are not
debating it either.

A map *is* most valuable. A map is *not* a vector.
Sometimes you *need* a vector. A vector is *not* a convenient
replacement for a map in C++.

And of course there are maps for Ada, but this is OT.

OK, one can use a vector then. And as I said in other messages, it is
not difficult to define an array that takes arbitrary signed ranges, but
this does not make much sense in C++.
In other words, the direct equivalent of your array is probably
valarray/vector, ignoring the signed ranges.
--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 23 '05 #560
Ioannis Vranos wrote:
OK, one can use a vector then. And as I said in other messages, it is
not difficult to define an array that takes arbitrary signed ranges, but
this does not make much sense in C++.
In other words, the direct equivalent of your array is probably
valarray/vector, ignoring the signed ranges.

BTW does Ada provide dynamic arrays like vector/deque?

--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 23 '05 #561
On Wed, 23 Mar 2005 12:36:46 +0200, Ioannis Vranos wrote:
Pascal Obry wrote:
For a domain problem where you have to create an area centered on (0,0)
for example. What about a vector representing altitude, the sub-zero values
being under the water. Just some examples, I bet you'll be able to think about
lot more :)
I think an associative container like map fits better to this. What do
you do in Ada if you want to associate product names with prices, in the
style

productlist["something"]= 71.2;

or a name with a number (string with string) in an address book
application for example?

namelist["Obry Pascal"]="321-45563";


In general, we use ADT. It is also a recommended practice in C++, BTW. What
would you do with

namelist["Pascal Obry"]="+0 321/45563 ";

or

namelist["321-45563"]="Pascal Obry";

Note that both Ada and C++ support ADT. Ada's arrays is just an example of
ADT. It is possible in C++ to implement an array as a set of classes though
it will be much more verbose and suffer from numerous drawbacks.
Also may you tell me if that famous compile-time boundary checking
applies (can be used) to user-defined containers too?


Of course it does. It is no different. The bounds can be specified either
as discriminants or as generic parameters (the latter has C++ equivalent).
As for the types with discriminants, they can be statically/dynamically
constrained and this is propagated down to the implementation where the
constraints are used. If corresponding methods are inlined then nothing
prevents the compiler from checking statically known bounds at
compile-time.

I seems to me that you still missing the point. Ada's ability to check
bounds is based on the idea of constrained subtypes. It is a fundamental
concept which C++ lacks. (The only weak form of constraining C++ supports
is templates specialization.)

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
Jul 23 '05 #562

Ioannis Vranos <iv*@remove.this.grad.com> writes:
In the "STL like" library do you have something like valarray or vector?


We have vector.

Pascal.

--

--|------------------------------------------------------
--| Pascal Obry Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--| http://www.obry.org
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595
Jul 23 '05 #563
Ioannis Vranos wrote:
Georg Bauhaus wrote:
> We want a vector type indexed by values between M and N only *and* we
> want the compiler + tools to help us make data structures in accord
> with these ranges. We want it to take advantage of what it can learn
> from the type system which allows index range checking _at compile time_.
At first, it is easy to write


Not the point.
a container in C++ that accepts a
specified range for indexes.
A vector has an index range built into the language C++.
It was stated that type based indexing together with
attributes helps both the writer and the compiler.
No programmer effort needed.
The only reason that there is not one, is
because it does not make sense in C++
Interesting claim. I Don't buy it. It is just not available
in the language.
The [0, +] style maps closely what is
happening in the machine.
Another Off Topic.
Also it is possible to define range-checked at run-time, operations.
vector::at() is an example.
Why are you repeating this? Not the point.
vector is also a dynamic-type array, so placing compile-time bounds
checking isn't possible/doesn't make sense.
Elsewhere you say that it is possible and does make sense
to work around this lack using compile time assertions,
carfully placing them close to the object to which they are somehow
related. (Effectively creating an ad-hoc meta-language written in
templates. Only shows that the thing is indeed missing in C++.)

It makes sense to know the bounds of a container,
possibly in advance. Are you declaring that std::vector and
not knowing the bounds is the only reasonable thing to do in
programming?

Type attributes are a mode of expression, available with
types in Ada. You can build algorithms around language provided
attributes, for example bounds, without having to resort to
mere conventions and the hope that the compiler will do something
useful with the conventional items.
For fixed size arrays and containers it is true, the compiler does not
catch at compile time any out of boundaries access. However we can do
this explicitly, by using compile-time checked assertions.
In other words, C++ array like types don't have these properties.
I'm not saying this is catastrophic. It's just not available
unless you roll your own. This has consequences for how you write
your software. It has consequences for what your compiler can do.
Some of them are interesing, because of template computing.

> No. I mean a double subtype whose values range from N.M to N'.M'.

May you give an example for a container along with such a subtype?


It was given, starting this "sub"thread.
> Here you can see one point that you might want to demonstrate:
> The compiler won't tell you that there is something wrong
> with
>
> doors[10].SetOpen().SetNoVan();
>
> Worse, the program won't tell you either. This shows the missing
> link between vector indexing and the base type system in your
> approach. You could use
>
> doors.at(10).SetOpen().SetNoVan();
>
> and handle the exception _at run time_.
> In Ada, the compiler will tell you: "index value 10 is no good!"
> because the array "doors" can only be indexed by values effectively
> between 0 .. 9. These and only these are the values of the type
> enumerating the ten doors, and only these are allowed as index
> values x in expressios doors(x).
> No exception handling, no .at() needed when you listen to your
> compiler and fix the indexing error before you deliver a program.
> You get this for free as a result of the language's type handling
> at compile time.

Will the Ada compiler tell you this, for user-defined types too?


An enum is a user defined type.
Any unconstrained type (including more than array types)
entails constrained objects, and the compiler may have a word
in this.
Maybe, if one gets used to template programming, the basis of the
language is deliberately ignored?
Ada just doesn't need templates for many things that are tried
using templates in C++, because the things are already in the
language.

Or is
this restricted to built-in arrays? If the latest is true, then its
value isn't that much.
Every bug that is found at compile time is worth a lot
to me.

Try telling someone that useful array attributes, and type attributes
and object attributes in general, aren't of much value.
What else are .begin() and .end() other than roll-my-own replacements
for something that C style arrays lack, *language-wise*?
Those working for an insurance company, in a stocks related business,
in math related computing, statistics, etc. use *Array Programming
Languages*. Why would they be doing this if good array support
isn't worth something? What is the value of good array support in
all those valuable Fortran computing libraries?

Are you saying that a robust base type system isn't worth it because
of the STL?
Consider the effort is takes to get a useful STL made of
basically, at-least-so-many-bits integers, pointers, and malloc().

Please answer this question:
Why is vector not implemented using vector? (I'm serious.)
I think that the value of defined subranges in the style
-1000, -400 has not any practical use.
Any evidence?
> - Given an enum, and
> - given a language that allows the enum as a basis for the construction
> of an array type in the type system ... > (a) useful names for objects in your problem domain, checked at
> compile-time

What do you mean by names?


I mean object names (enumerated identifiers), not strings. Like in

typedef std::map<Some_Enum, int> Slow_Array;

This is not the same as

typedef std::vector<int> Faster_Array:

> (b) a conceptual link between the enum (naming the single items) and
> a container _type_ (containing these items); you cannot use anything
> but these named numbers for indexing

Which has no value in the world of C++, but I guess many things in Ada
depend on this.


You just gave an example of an assertion working around
the indexing issue... So apparently proper indexing has
a value in the world of C++, contradicting your claim.

> (c) the fastest possible access, for both reading and writing, possibly
> checked at compile time

Fastest possible access in C++.


The fastest possible element access in C++ is dereferencing a pointer.
The fastest possible element access in STL/C++ is varying with container
and method.

Compare

type Floor_Number is -2 .. 52;
-- sky scraper

type Door_Count is array(Floor_Number) of Natural;

versus

typedef char Floor_Number;
typedef std::map<Floor_Number, unsigned int> Door_Count;

We are discussing fastest access, and type based indexing.

So my question again, what does it take, in C++, to replace
Floor_Number as typedefed above with something that matches
the given building's floors exactly? What is the price to pay?

is the Ada compile-time boundaries checking available
to user-defined containers?
We are discussing the value of a container that doesn't *need*
to be defined because it is built into the language's type system,
with all bells and whistles and compiler help. No user definition
is *needed*, it's already there.

If you insist on leading us astray and on constructing your own
containers: The presence of bounds checking in programmer defined
ADTs depends on how they are defined.
can compile-time assertions be used?
The compiler will warn you when it can evaluate the expression
in a pragma assert at compile time. More importantly, the
compiler will use the compile-time checking required by Ada
array types. No need for programmer assertions expressed
using add-on templates.
Of course
one can always program improperly. :-)


I did say that this is not the point, didn't I?

The point is, how does a language help you writing
correct and efficient programs. C++ the language doesn't
have fixed size built in arrays. In some problem domains,
fixed size arrays are very useful, if not essential.

This is why many programming languages have them.

Georg
Jul 23 '05 #564
Ioannis Vranos wrote:
Georg Bauhaus wrote:
Compare log(10^6) to 1.

I can't see how O(log(n)) isn't huge when compared to
O(1), in an inner loop for containers of size 10^6.

OK, but besides the fact that only explicit entries in map occupy space,


Yet another issue having nothing to do with how
Ada arrays compare to C++ style arrays when the problem
requires plain arrays, not sparse arrays.
Also, as I said it is not difficult to define an array that takes
arbitrary signed ranges, but this does not make much sense in C++.
Any evidence?

In other words, the direct equivalent of your array is probably
valarray/vector, ignoring the signed ranges.
"ignoring" seems to be an attitude in your responses. ;-)
built-in arrays, which means is not of much use.
Do you know what a built in array really is, and what it does?

Also the lack of a "STL like" library in Ada until now probably sounds
like that Ada lacks much of the high-level abstraction that C++ provides.


Oh, come on. You are making claims about a language and
then guess about it? For many things a library was just not
needed in Ada. The language already provided what was needed,
including the high level of abstraction.

I've tried to picture the higher level of abstraction
in the Ada base type system that is just not present in C++.
For example, there is no need for .begin() and .end() in Ada
because it has always had these as attributes. In Ada it has always
been possible to write a generic array algorithm simply by requiring
that the G in <typename G, ...> is of an array type. There was
no need to add the hot new things like Can_Copy because they
were already in the language.

There have always been well designed ADT libraries (including
graph support). One of them has actually been ported from Ada 83 to C++,
and later to Ada 95 (Booch components).

Come to think of it, I don't know of anything like task *types*
and shared variable *types* built into the language C++.
This is right under your nose as high level abstractions
in plain Ada program structuring.

µC++ adds concurrency support to the C++ type system, at a somewhat
lower level of abstraction than Ada.
Still, µC+++ reimports the weaknesses of the precursor languages.
Sad, but successful because of mass momentum.

Georg
Jul 23 '05 #565
Ioannis Vranos wrote:
OK, although O(log(n)) is fairly cheap, let's stick to O(1). However
personally I think that the value of defined subranges in the style
-1000, -400 has not any practical use.


So? Let me take a look at some current project:

|type DAC_Range is new Interfaces.Unsigned_8;
|type Offset is new Interfaces.Integer_8;
|
|-- lookup tables are faster
|type Offset_Skew is array(Offset) of DAC_Range;

So the array indices are - of course - from -127 to 128.

(Of course you can remap that to 0 to 255, but because I am calculating
in signed range for relatively obvious reasons, this is much more
convenient.)
Vinzent.

--
worst case: The wrong assumption there actually is one.
Jul 23 '05 #566
"Dr. Adrian Wrigley" <am**@linuxchip.demon.co.uk.uk.uk> writes:
Wouldn't that be std::map in C++?
and in Ada 2005,

Ada.Containers.Hashed_Maps and Ada.Containers.Hashed_Maps


Ada 2005 will have both ordered ("sorted") maps and hashed maps. The
current C++ standard only has ordered maps.

I have probably missed a trick in the C++, but I couldn't get
std::map code to compile (except in the trivial cases):

#include <map>

struct compoundindex {
int a, b, c;
};
This type doesn't have a relational operator, which you need to
instantiate the map.

--
The Ada associative arrays from the new draft standard
are specified as something like:

generic
type Key_Type is private;
type Element_Type is private;
with function Hash (Key : Key_Type)
return Hash_Type is <>;
with function Is_Equal_Key (Left, Right : Key_Type)
return Boolean is "=";
with function "=" (Left, Right : Element_Type)
return Boolean is <>;
package Ada.Containers.Hashed_Maps is...
Yes, but the analog to the C++ map is Ada.Containers.Ordered_Maps, not
the hashed map.

Which clearly won't work unless you can find the three
function generic parameters. I don't see how this can be
used easily in a generic context.
But this is true of C++ as well. There's no magic: your key either
needs a relational operator (for the ordered map), or it needs a hash
function (for the hashed map).

I don't think I am being *that* unreasonable in asking for arrays
indexed by arbitrary types, without jumping through hoops :)


Requiring that the key used to instantiate a hashed map have a hash
function hardly constitutes "jumping through hoops." In any event, you
probably want an ordered map anyway:

generic

type Key_Type is private;

type Element_Type is private;

with function "<" (Left, Right : Key_Type) return Boolean is <>;

with function "=" (Left, Right : Element_Type) return Boolean is <>;

package Ada.Containers.Ordered_Maps is
in which case all you need is a relational op:

function "<" (L, R : Compound_Index) return Boolean is
begin
if L.A < R.A then
return True;
end if;

if L.A > R.A then
return False;
end if;

if L.B < R.B then ...
end;

package Compound_Index_Maps is
new Ada.Containers.Ordered_Maps (Compound_Index, Float);

declare
M : Compound_Index_Maps.Map;
begin
M.Include (Key => (1, 2, 4), New_Item => 0.123);
end;

Jul 23 '05 #567
Ioannis Vranos wrote:
Ioannis Vranos wrote:
OK, one can use a vector then. And as I said in other messages, it is not difficult to define an array that takes arbitrary signed ranges, but this does not make much sense in C++.
In other words, the direct equivalent of your array is probably
valarray/vector, ignoring the signed ranges.

BTW does Ada provide dynamic arrays like vector/deque?

--
Ioannis Vranos


Ciao,

I think we don't have to care about the presence of a high-level
construct like whatever container. When C++ hadn't yet standardised
containers, everyone could actually build these higher-level structures
by himself. The only problem is standardisation. If you have languages
that are sufficienly low-level like C++ and Ada you can manufacture
every type of algorithm and containers you need.

You build higher-level components by using lower-level built-in
language features. Every compile-time or run-type check that you can
have for built-in types you "inherit" for user created structures. This
is said to answer your past question about Ada having or not same
checks for built-in types and user defined types.

I suppose std::vector is a simple array which must be copied to a
larger one in order to insert a new element while it is full. You know
it can be done in Ada too.

What's more in Ada is that you can, in a standardised way, directly
create low-level representation of user defined types with a lot of
attributes that C++ doesn't provide. Ada programmers prefer to build
their own types rather than using built-in Integer, Float, Long_Float
(int, float, double) and so on in order to gain a much finer control.

In Ada you can decide representation attributes like range, digit,
delta, mod, address, alignment, size, byte-order (little or big endian)
in record component, and many other things like these. As an example
you can write:

type Counter is new Integer;
for Counter'Size use 48;
for Counter'Alignment use 16;

What's more, you get a compiler error if your machine can't use some
sort of representation you need in order to free you from knowing how
much space a type can provide.

You said that real C++ code hardly need to specify ranges, because you
should be careful not to assign a value that can't be held by a
variable of some specific type. Imagine you have know a variable is to
hold numbers not larger than 99_999 and you choose to store them in an
"int" knowing that you have enough space. When later you port your
program to a machine where "int" is 16 bits you don't have any warning
from a C++ compiler and program run for years until for some reason
that variable is assigned with say 86_000. I think you know what
happens..

If you had that type declared as "type Var_T is range 0 .. 99_999;", at
the very moment you port your program to this new machine the compiler
would choose the correct size to hold values of that type so program is
no more restricted to this 16 bits C++ "int" and consequently won't
raise this bug.

Do you still think you don't need ranges?

Regards,

fabio de francesco

Jul 23 '05 #568

Robert A Duff wrote:
"Frank J. Lhota" <NO******************@verizon.net> writes:
<ad******@sbcglobal.net> wrote in message
news:9l**************@newssvr21.news.prodigy.com.. .
And that is the unfortunate aspect of the language: its foundation on C.
I once heard Stroustrup confess that, if he had had his druthers, he would not have started with C as the seed language.


Stroustrup said in an interview that his preference would have been Algol with classes.


Hmm... Isn't that language called Simula 67? ;-)
I think that I probably would have preferred that as well!


- Bob


The Algol I was talking about in that context was Algol68. The result
would have been a more flexible and efficient language than Simula67
and a cleaner language than C++ became. Unfortunately, there was no
chance of such a language succeeding at that time and place - the
understanding of the basic concepts among the intended users and the
infrastructure needed to get work done were missing. It would have been
yet another beautiful, but stillborn, language. C++ was designed in
response to pressing problems, not as a 10-year project aimed at
abstract beauty. I think that in the long run, it actually gained from
that.

If you want to understand how and why C++ was done, have a look at
Stroustrup: "The Design and Evolution of C++" (Addison-Wesley). If
nothing else, it might help you to avoid revisionist history and wild
conjecture. I think that documenting decisions about major tools is
important and should not be confused with "confessions".

I chose C as a base for C++ because - among the many languages I knew
of - it was the one that came closest to my needs. It wasn't perfect
and C compatibility became a bigger problem than I had bargained for,
but noone "forced me" (as is conjectured, incl. in this thread).

And no, C++ was never meant solely for object-oriented programming
(when defined as programming using class hierarchies). Support for data
abstraction and procedural programming was mentioned in my earliest
papers, and a 1981 paper grapples (rather unsuccessfully) with the
basics of generic programming.

-- Bjarne Stroustrup; http://www.research.att.com/~bs

Jul 23 '05 #569
"bjarne" <bj****@gmail.com> writes:
Robert A Duff wrote:
"Frank J. Lhota" <NO******************@verizon.net> writes:
<ad******@sbcglobal.net> wrote in message
news:9l**************@newssvr21.news.prodigy.com.. .
> And that is the unfortunate aspect of the language: its foundation on C. >
> I once heard Stroustrup confess that, if he had had his druthers, he would > not have started with C as the seed language.

Stroustrup said in an interview that his preference would have been Algol with classes.
Hmm... Isn't that language called Simula 67? ;-)
I think that I probably would have preferred that as well!


- Bob


The Algol I was talking about in that context was Algol68.


OK, fair enough. I *did* put a smiley there!
...The result
would have been a more flexible and efficient language than Simula67
and a cleaner language than C++ became.
I agree.
... Unfortunately, there was no
chance of such a language succeeding at that time and place - the
understanding of the basic concepts among the intended users and the
infrastructure needed to get work done were missing. It would have been
yet another beautiful, but stillborn, language. C++ was designed in
response to pressing problems, not as a 10-year project aimed at
abstract beauty. I think that in the long run, it actually gained from
that.

If you want to understand how and why C++ was done, have a look at
Stroustrup: "The Design and Evolution of C++" (Addison-Wesley).
I've read it. (And enjoyed it very much!)
... If
nothing else, it might help you to avoid revisionist history and wild
conjecture. I think that documenting decisions about major tools is
important and should not be confused with "confessions".
I apologize for what might seem like "wild conjecture". That wasn't my
intent -- I was just making a silly joke based on the phrase "Algol with
classes". Sorry.
I chose C as a base for C++ because - among the many languages I knew
of - it was the one that came closest to my needs. It wasn't perfect
and C compatibility became a bigger problem than I had bargained for,
As one of the designers of Ada 95, I know very well what it is like to
design a language when compatibility is a constraint.
but noone "forced me" (as is conjectured, incl. in this thread).

And no, C++ was never meant solely for object-oriented programming
(when defined as programming using class hierarchies). Support for data
abstraction and procedural programming was mentioned in my earliest
papers, and a 1981 paper grapples (rather unsuccessfully) with the
basics of generic programming.

-- Bjarne Stroustrup; http://www.research.att.com/~bs


- Bob
Jul 23 '05 #570
Matthew Heaney wrote:
"Dr. Adrian Wrigley" <am**@linuxchip.demon.co.uk.uk.uk> writes:

Wouldn't that be std::map in C++?

and in Ada 2005,

Ada.Containers.Hashed_Maps and Ada.Containers.Hashed_Maps

Ada 2005 will have both ordered ("sorted") maps and hashed maps. The
current C++ standard only has ordered maps.


Just replying to this point.. The TR1 library edition will also have
hashed maps, although I suspect Ada 2005 might beat it out :) (Although
G++ 4.0 will have them as contained in the (almost) final version of the
TR1 standard).
Jul 23 '05 #571
"bjarne" <bj****@gmail.com> wrote in message
news:11**********************@o13g2000cwo.googlegr oups.com...
The Algol I was talking about in that context was Algol68.
Sorry for the confustion. I had assumed that the term Algol would
universally be interpreped as Algol68. Clearly this assumption was wrong,
and I should have added the "68" suffix to clarify the matter.
The result
would have been a more flexible and efficient language than Simula67
and a cleaner language than C++ became. Unfortunately, there was no
chance of such a language succeeding at that time and place - the
understanding of the basic concepts among the intended users and the
infrastructure needed to get work done were missing. It would have been
yet another beautiful, but stillborn, language. C++ was designed in
response to pressing problems, not as a 10-year project aimed at
abstract beauty. I think that in the long run, it actually gained from
that.
Having no Simula67 experience, and no readily available way to get such
experience, I cannot comment on the merits of that language. My exposure to
Algol, however, leads me to believe that it would make an excellent
foundation for a modern OO language. I understand that "Algol68 with
classes" would have virtually no chance of succeeding, although I find the
lack of viability of such a beautiful langage lamentable.
If you want to understand how and why C++ was done, have a look at
Stroustrup: "The Design and Evolution of C++" (Addison-Wesley). If
nothing else, it might help you to avoid revisionist history and wild
conjecture. I think that documenting decisions about major tools is
important and should not be confused with "confessions".
I have read the book, and I can recommend it highly.
I chose C as a base for C++ because - among the many languages I knew
of - it was the one that came closest to my needs. It wasn't perfect
and C compatibility became a bigger problem than I had bargained for,
but noone "forced me" (as is conjectured, incl. in this thread).

And no, C++ was never meant solely for object-oriented programming
(when defined as programming using class hierarchies). Support for data
abstraction and procedural programming was mentioned in my earliest
papers, and a 1981 paper grapples (rather unsuccessfully) with the
basics of generic programming.

-- Bjarne Stroustrup; http://www.research.att.com/~bs


Jul 23 '05 #572

"Ioannis Vranos" <iv*@remove.this.grad.com> wrote in message
news:1110608948.651588@athnrd02...

Myself thinks though that this whole range specialisation thing is
non-sense for regular application programming at least.

Perhaps for your kind of programming, the Ada type model
would be unnecessary. In fact, for many Ada programs, it
is not essential. However, the ability to refine the meaning
of a type, in Ada, is quite useful for many reasons when writing
large-scale software where a lot of people will be involved in
the process.

1. It makes the program more readable because unique
names for types can be given meaningful names.

2. It enforces name equivalence within the type system, rather
than relying on structural equivalence. This deprives the
programmer of many hours of entertaining debugging sessions.

3. One can do simple membership tests on the specified ranges,
thereby eliminating such annoying constructs as:
if X >= 20 and X <= 50 then ...
which sometimes leads to interesting errors.

4. The scope and visibility rules, one of the most powerful features
of Ada for creating safe software, ensure that type names will
not be automatically visible everywhere in the code.

These are just a few benefits. I realize that, any one of these, taken by
itself, might not be impressive. However, in practice, the combined
power of them tends to make it easier to produce fewer errors during
the development process. You might think of this model as an assist
to the programmer in constraining the environment prior to coding in
that environment. Such constraints have proven useful to those who
learn to use them. For those who choose other courses of action,
no amount of argument, proof, or demonstration of benefits will suffice.

Richard Riehle
Jul 23 '05 #573

"Ioannis Vranos" <iv*@remove.this.grad.com> wrote in message
news:1111464133.508323@athnrd02...

OK. I read your C++ example with care and interest.
Then I compared it, once again, with the example I wrote.

I wonder if you truly think the two examples are equlivalent
in all respects. I must confess that, if the C++ example
were an accurate representation of how one would solve
this problem in that language, I would abandon C++ for
all time.

A key goal of Ada is to produce readable code, not simply
writeable solutions in cryptic code. Who, upon encountering
the C++ example in your post, would be able to quickly
apprehend the meaning, the intent, or the result of this
code?

I rest my case.

Richard Riehle
Jul 23 '05 #574

"Ioannis Vranos" <iv*@remove.this.grad.com> wrote in message
news:1111572591.296439@athnrd02...

C++ maps on both. However I guess Ada maps on both too since it is a
systems programming language. :-)

Rene Descartes originally developed his coordinate geometry in
quadrant One. That worked fine for a long time. When negative
quadrants were proposed, by later mathematicians, many wondered
what they were good for.

The early Greek mathematicians found no use for a number representing
zero. The reason: their number system was based on geometry and
there was no need to represent a non-existent geometrical object.

Some ancient cultures started their own number systems from two
because they saw no point in counting until there was more than
one of something.

There are many cases, in programming, where one wants to map the
solution space to the problem space. In the real world, not every
problem space originates at zero. Quite often, it is useful to define
the solution space beginning with 1 instead of zero. This makes
algorithms for such problems more straightforward. Other times,
one might want to begin the indexing at a number greater than 1.

type Channel is range 2..136;
type Active_Channels is array(Channel) of Boolean;

In practice, particularly in real-time systems, the ability to set the
array index to a range that closely reflects the realities of the
problem space can be quite helpful. It also acts as part of the
self-documenting aspect of the solution space.

Richard Riehle
Jul 23 '05 #575

"Ioannis Vranos" <iv*@remove.this.grad.com> wrote in message
news:1111522653.164049@athnrd02...

In other words it does not make much sense to have signed indexes.
Otherwise it is easy and possible.

1. Signed indices are extremely valuable when doing certain
kinds of mathematical modeling.

2. Your example did not use "straight" C++. Instead, you relied
on the Vector template. Doing the same thing, in Ada, we
could have multiplied the power of this problem even more.

3. I have so often encountered the question, "But why would you
want to do that? in my career, that I am still amazed when I
hear it yet again.

Regarding number 3, I wish Ada had a good model of multiple
inheritance. I don't mean the somewhat haphazard model of
C++, but rather something like the multiple inheritance of
Eiffel. When someone asks me, wrt multiple inheritance, "But
why would you want to that? it drives me a little crazy.

There are lots of good uses for multiple inheritance. However,
there are also lots of dangers in it. Ada correctly comes down
on the side of safety, but I do sometimes wish it were available.

Richard Riehle
Jul 23 '05 #576
ad******@sbcglobal.net wrote:
Regarding number 3, I wish Ada had a good model of multiple
inheritance. I don't mean the somewhat haphazard model of
C++, but rather something like the multiple inheritance of
Eiffel. When someone asks me, wrt multiple inheritance, "But
why would you want to that? it drives me a little crazy.

There are lots of good uses for multiple inheritance. However,
there are also lots of dangers in it. Ada correctly comes down
on the side of safety, but I do sometimes wish it were available.


It will have multiple inheritance of interfaces (a la Java) in
Ada2005 - is that enough?

Cheers

-- Martin

Jul 23 '05 #577
On Wed, 23 Mar 2005 17:26:12 +0000, adaworks wrote:

1. It makes the program more readable because unique
names for types can be given meaningful names.

2. It enforces name equivalence within the type system, rather
than relying on structural equivalence. This deprives the
programmer of many hours of entertaining debugging sessions.

3. One can do simple membership tests on the specified ranges,
thereby eliminating such annoying constructs as:
if X >= 20 and X <= 50 then ...
which sometimes leads to interesting errors.

4. The scope and visibility rules, one of the most powerful features
of Ada for creating safe software, ensure that type names will
not be automatically visible everywhere in the code.


And you can do really handy stuff passing arrays not indexed from 0,
and accessing the attributes:

-- No particular purpose but to demo
type MyString is array (Integer range <>) of Integer;

procedure UpdateString (Blob : in out MyString; K : Integer) is
begin

if Blob'Length = 0 then
return;
elsif Blob'Length = 1 then
Blob (Blob'First) := Blob (Blob'First) + K;
return;
else
UpdateString (Blob (Blob'First .. Blob'First+Blob'Length/2-1), 19);
UpdateString (Blob (Blob'First+Blob'Length/2 .. Blob'Last), 27);
return;
end if;

end UpdateString;
....
UpdateString (Fred (10 .. 19), 0);

In this case, you make the intent clear which part is being
updated in each level of recursion. You get the bounds checking
in each level, to make sure it is not stepping outside the specific
part of the array passed.

I don't think the C++ equivalent would be so clear, since you would
have to add extra parameters saying what part of the array you are using,
and you would have to add extra bounds checking manually, even
if the container class checked against the overall bounds.

The C++ users who are so concerned about the overhead of storing
bounds in the type have to weigh the cost against storing the
bounds elsewhere and passing them as another couple of parameters.
It's rare that Ada code would have to store bounds which wouldn't
otherwise have to be stored somewhere anyway. (did we cover this already?)
--
Adrian

Jul 23 '05 #578
Peter Amey wrote:

[ ... ]
Actually, a close reading of the thread should have made it clear
that the additional safety is indeed "free". Since the majority
of Ada's checks are compile time they do not impact on run-time
efficiency.
Some of the cited cases provide checks that are free in terms of
run-time, but run-time is hardly the major cost in most software.
Though I haven't done so recently, back when I used Ada, nowhere close
to all of the checks were free even in terms of run-time either.

Furthermore, even when the run-time check itself imposes no extra code
execution, that doesn't mean it's necessarily free in terms of run-time
cost either. Simple economic reality is that writing a good compiler is
NOT a quick, cheap, or simple thing to do. Generally speaking, it's
done to a budget of some sort and time and effort that's put into
compile-time checks more or less directly translates into time and
effort that was NOT put into better code generation and optimization.
This can be ameliorated in a case like GNAT, where the Ada compiler
shares a back-end with something else, but the effect is almost never
really eliminated -- time and effort are almost always limited
resources, so expending them in one way nearly always reduces their
expenditure elsewhere.
Where Ada's goals can only be met by run-time checks these are
no more expensive than equivalent manually-inserted checks in
any other language (and are often less because Ada provides the
compiler with more information by which to judge when they can
safely be optimised away).
Maybe...or maybe not. IME, absolute statements about generalities (e.g.
all implementations of a language) are rarely accurate. Ada compilers
vary quite widely, and I've certainly seen some emit code that included
checks that were logically unnecessary. I'd guess that the current
compilers are better, but perfection in this respect would surprise me.

In the end, my experiece has been that Ada compilers produce _slightly_
worse code in general than C and C++ compilers, but it would take
considerable work to determine how much of this is due to the source
language, and how much simply because their smaller market share
supports less time and effort in optimization. In fairness, I should
add that the differences are rarely very noteworthy. In most typical
situations, if one produces adequately fast output, so will the other.
Of course, if you're dealing with hard real-time requirements and a C++
compiler meets the requrement with only .5% to spare, there's a pretty
fair chance that Ada would fail -- but this sort of situation is
unusual (probably even rare).

[ ... ]
It should also have been clear from the thread that Ada imposes no
limits on expressiveness.
Nonsense -- examples of Ada expressing a few specific concepts have
been given, but this hardly proves a lack of limits. The fact is,
_every_ programming language places severe limits on expressiveness;
anybody who believes otherwise simply hasn't given the subject much
real thought. Programming languages in general express only a small
range of specific actions that are relevant to (most) computers. By
design, none of them is really expressive in areas such as human
emotions.

Even sticking to programming types of things, Ada has some limits to
its expressiveness.

Just for one obvious example, Ada doesn't provide an easy way to
express/do most of the things one can do with the C or C++
preprocessor. It provides some alternative in _some_ cases, but quite
frankly, these are really the exceptions rather than the rule.

Some areas are somewhat more questionable -- calling a class a "tagged
record" is clearly a mistake, but it's open to question whether it
should be classified under poor expression of the concept, or just
general idiocy.

The Ada folks who insist that things should be part of the base
language rather than an add-on library may have strings, but have
nothing equivalent to a dtor in C++. The possible presence of garbage
collection does little to mitigate this, as dtors are useful for _far_
more than just releasing memory when no longer in use. Ada even tacitly
admits to this shortcoming by providing Ada.Finalization in the
library. My understanding, however, is that this requires anything that
wants a destructor be derived from their base class (oops -- their base
tagged record). This may be usable, but it's hardly what I'd call a
clean expression of the concept. In fairness, I should add that I've
never used Ada.Finalization, so my understanding of it may well be
flawed, and corrections about this area would be welcome.

Speaking of strings, I'll digress for a moment: personally, I find it a
bit humorous when Ada advocates talk about things like having five
string types as an advantage. IMO, the need, or even belief, that five
string types are necessary or even useful is a _strong_ indication that
all five are wrong.

Ada's exception handling is also primitive at best (exceptionally so,
if you'll pardon a pun). In particular, in Ada what you throw is
essentially an enumaration -- a name that the compiler can match up
with the same name in a handler, but nothing more. Only exact matches
are supported and no information is included beyond the identity of the
exception.

In C++ you can throw an arbitrary type of object with an arbitrary
value. All the information relevant to the situation at hand can be
expressed cleanly and directly. The usual inheritance rules apply, so
an exception handler can handle not only one specific exception, but an
entire class of exceptions. Again, this idea can be expressed directly
rather than as the logical OR of the individual values. And, once
again, the addition of tagged records to Ada 95 testifies to the fact
that even its own designers recognized the improvement this adds in
general, but (whether due to shortsightedness, concerns for backward
compatibility or whatever) didn't allow this improvement to be applied
in this situation.
Can you say what led you to the opposite conclusion?


Study and experience. Can you say what leads you to believe your own
claim?

--
Later,
Jerry.

The universe is a figment of its own imagination.

Jul 23 '05 #579
Pascal Obry wrote:
We have vector.

If it is also defined in std namespace, I am going to smile.

--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 23 '05 #580
fabio de francesco wrote:
Ciao,

I think we don't have to care about the presence of a high-level
construct like whatever container. When C++ hadn't yet standardised
containers, everyone could actually build these higher-level structures
by himself. The only problem is standardisation. If you have languages
that are sufficienly low-level like C++ and Ada you can manufacture
every type of algorithm and containers you need.

You build higher-level components by using lower-level built-in
language features. Every compile-time or run-type check that you can
have for built-in types you "inherit" for user created structures. This
is said to answer your past question about Ada having or not same
checks for built-in types and user defined types.

OK.

I suppose std::vector is a simple array which must be copied to a
larger one in order to insert a new element while it is full. You know
it can be done in Ada too.

It is not that expensive. An implementer reserves some more space so as
to avoid frequent reallocations, and vector provides reserve() method to
allocate unitialised space for objects since the beginning by yourself,
if you are going to insert many objects later, so as to avoid
reallocation. For example:
// Contains 10 ints initialised to 0.
vector<int> vec(10);

// Reserves unitialised memory space for 1000 ints in total
vec.reserve(1000);
What's more in Ada is that you can, in a standardised way, directly
create low-level representation of user defined types with a lot of
attributes that C++ doesn't provide. Ada programmers prefer to build
their own types rather than using built-in Integer, Float, Long_Float
(int, float, double) and so on in order to gain a much finer control.

In Ada you can decide representation attributes like range, digit,
delta, mod, address, alignment, size, byte-order (little or big endian)
in record component, and many other things like these. As an example
you can write:

type Counter is new Integer;
for Counter'Size use 48;
for Counter'Alignment use 16;

What's more, you get a compiler error if your machine can't use some
sort of representation you need in order to free you from knowing how
much space a type can provide.

You said that real C++ code hardly need to specify ranges, because you
should be careful not to assign a value that can't be held by a
variable of some specific type. Imagine you have know a variable is to
hold numbers not larger than 99_999 and you choose to store them in an
"int" knowing that you have enough space. When later you port your
program to a machine where "int" is 16 bits you don't have any warning
from a C++ compiler and program run for years until for some reason
that variable is assigned with say 86_000. I think you know what
happens..

The standard guarantees the minimum ranges, for int can hold at least
16-bit values and long at least 32-bit values.

If you had that type declared as "type Var_T is range 0 .. 99_999;", at
the very moment you port your program to this new machine the compiler
would choose the correct size to hold values of that type so program is
no more restricted to this 16 bits C++ "int" and consequently won't
raise this bug.

Do you still think you don't need ranges?

Ranges are a nice thing to have, however if you are provided with
minimum range guarantees, this also does the job.
I would prefer compiler error messages for out of range assignments
though. And I wonder what backwards compatibility (apart from -1
assignment to unsigned integral types) this would break.

--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 23 '05 #581

Jerry Coffin wrote:

Speaking of strings, I'll digress for a moment: personally, I find it a bit humorous when Ada advocates talk about things like having five
string types as an advantage. IMO, the need, or even belief, that five string types are necessary or even useful is a _strong_ indication that all five are wrong.


It's the same as in C++:

char[]
wchar_t[]
std::string
std::wstring

The string types in Ada95 are very similar:

String
Wide_String
Unbounded_String
Wide_Unbounded_String

Jul 23 '05 #582
Dmitry A. Kazakov wrote:
In general, we use ADT. It is also a recommended practice in C++, BTW. What
would you do with

namelist["Pascal Obry"]="+0 321/45563 ";

or

namelist["321-45563"]="Pascal Obry";

I am not sure what you mean here, input validation should take place
before such assignment.

Note that both Ada and C++ support ADT. Ada's arrays is just an example of
ADT. It is possible in C++ to implement an array as a set of classes though
it will be much more verbose and suffer from numerous drawbacks.

I am not sure what you mean here either.

Of course it does. It is no different. The bounds can be specified either
as discriminants or as generic parameters (the latter has C++ equivalent).
As for the types with discriminants, they can be statically/dynamically
constrained and this is propagated down to the implementation where the
constraints are used. If corresponding methods are inlined then nothing
prevents the compiler from checking statically known bounds at
compile-time.

I seems to me that you still missing the point. Ada's ability to check
bounds is based on the idea of constrained subtypes. It is a fundamental
concept which C++ lacks. (The only weak form of constraining C++ supports
is templates specialization.)

OK then, Ada is probably better in this area.

--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 23 '05 #583
Ioannis Vranos wrote:
Pascal Obry wrote:

We have vector.


If it is also defined in std namespace, I am going to smile.


It's declared as a child of Ada.Containers. It's otherwise very
similar to std::vector. (Actually, that's true of all of the
containers in the standard library, since STL was the inspiration.)

Jul 23 '05 #584
Matthew Heaney wrote:
Jerry Coffin wrote:

Speaking of strings, I'll digress for a moment: personally, I find
it a bit humorous when Ada advocates talk about things like having
five string types as an advantage. IMO, the need, or even belief,
that five string types are necessary or even useful is a _strong_
indication that all five are wrong.


It's the same as in C++:

char[]
wchar_t[]
std::string
std::wstring

The string types in Ada95 are very similar:

String
Wide_String
Unbounded_String
Wide_Unbounded_String


char[] and wchar_t[] are arrays, not strings. C++ really only has one
string type: std::basic_string. std::string and std::wstring are not
types of their own at all, but simply typedefs as:

typedef std::basic_string<char> string;
typedef std::basic_string<wchar_t> wstring;

In addition, one of the major arguments the Ada fans have used here is
that Ada's strings are built-in, NOT added as a class like in C++. If
C++ had been designed from the beginning with a string class, the
array-based "stuff" probably wouldn't exist at all.

BTW, in case anybody really cares, yes I apply the same standard to
C++: while its string handling facilities are fewer and IMO better than
Ada's, they're still far short of perfect.

--
Later,
Jerry.

The universe is a figment of its own imagination.

Jul 23 '05 #585
Jerry Coffin wrote:
Just for one obvious example, Ada doesn't provide an easy way to
express/do most of the things one can do with the C or C++
preprocessor. It provides some alternative in _some_ cases, but quite
frankly, these are really the exceptions rather than the rule.
That 'problem' isn't unique to Ada - I can't think of another
language that *does* define a pre-processor.

And if you like a preprocessor - just use one! You can always write
a makefile/.bat/.com/<whatever> to invoke the preprocessor before the
compiler is called. GNAT comes with an Ada-centric preprocessor but
there is nothing to stop you using the 'C' one.

Ada's exception handling is also primitive at best (exceptionally so,
if you'll pardon a pun). In particular, in Ada what you throw is
essentially an enumaration -- a name that the compiler can match up
with the same name in a handler, but nothing more.
See Ada.Exceptions - perhaps not as elegant but it does the job and
back when the first exception mechanism for Ada was designed, I doubt
there was much call for anything other than a 'this fault has occured'
style exception. At the time, I'd guess that 90%+ of all code in
exsistance was COBOL, C or FORTRAN - none of which had any exception
handling!

Only exact matches
are supported and no information is included beyond the identity of
the exception.
True for Ada83 but not so in Ada95 - again see Ada.Exceptions and
getting expanded again in Ada2005.
And, once
again, the addition of tagged records to Ada 95 testifies to the fact
that even its own designers recognized the improvement this adds in
general, but (whether due to shortsightedness, concerns for backward
compatibility or whatever) didn't allow this improvement to be applied
in this situation.


Almost certainly backwards compatibility - but I'm sure Bob and/or Randy
could shed more light on that...

Cheers

-- Martin
Jul 23 '05 #586
Georg Bauhaus wrote:
A vector has an index range built into the language C++.
It was stated that type based indexing together with
attributes helps both the writer and the compiler.
No programmer effort needed.

Elsewhere you say that it is possible and does make sense
to work around this lack using compile time assertions,
carfully placing them close to the object to which they are somehow
related. (Effectively creating an ad-hoc meta-language written in
templates. Only shows that the thing is indeed missing in C++.)

It makes sense to know the bounds of a container,
possibly in advance. Are you declaring that std::vector and
not knowing the bounds is the only reasonable thing to do in
programming?

Type attributes are a mode of expression, available with
types in Ada. You can build algorithms around language provided
attributes, for example bounds, without having to resort to
mere conventions and the hope that the compiler will do something
useful with the conventional items.

OK, I think you are right. C++ lacks these, and I wonder why additional
keywords enabling this are not added in language proposals for future
standard revision (C++0x).
For fixed size arrays and containers it is true, the compiler does not
catch at compile time any out of boundaries access. However we can do
this explicitly, by using compile-time checked assertions.

In other words, C++ array like types don't have these properties.
I'm not saying this is catastrophic. It's just not available
unless you roll your own. This has consequences for how you write
your software. It has consequences for what your compiler can do.
Some of them are interesing, because of template computing.

> No. I mean a double subtype whose values range from N.M to N'.M'.

May you give an example for a container along with such a subtype?

It was given, starting this "sub"thread.
> Here you can see one point that you might want to demonstrate:
> The compiler won't tell you that there is something wrong
> with
>
> doors[10].SetOpen().SetNoVan();
>
> Worse, the program won't tell you either. This shows the missing
> link between vector indexing and the base type system in your
> approach. You could use
>
> doors.at(10).SetOpen().SetNoVan();
>
> and handle the exception _at run time_.
> In Ada, the compiler will tell you: "index value 10 is no good!"
> because the array "doors" can only be indexed by values effectively
> between 0 .. 9. These and only these are the values of the type
> enumerating the ten doors, and only these are allowed as index
> values x in expressios doors(x).
> No exception handling, no .at() needed when you listen to your
> compiler and fix the indexing error before you deliver a program.
> You get this for free as a result of the language's type handling
> at compile time.

Will the Ada compiler tell you this, for user-defined types too?

An enum is a user defined type.
Any unconstrained type (including more than array types)
entails constrained objects, and the compiler may have a word
in this.
Maybe, if one gets used to template programming, the basis of the
language is deliberately ignored?
Ada just doesn't need templates for many things that are tried
using templates in C++, because the things are already in the
language.

Or is this restricted to built-in arrays? If the latest is true, then
its value isn't that much.

Every bug that is found at compile time is worth a lot
to me.

Try telling someone that useful array attributes, and type attributes
and object attributes in general, aren't of much value.
What else are .begin() and .end() other than roll-my-own replacements
for something that C style arrays lack, *language-wise*?
Those working for an insurance company, in a stocks related business,
in math related computing, statistics, etc. use *Array Programming
Languages*. Why would they be doing this if good array support
isn't worth something? What is the value of good array support in
all those valuable Fortran computing libraries?

Are you saying that a robust base type system isn't worth it because
of the STL?
Consider the effort is takes to get a useful STL made of
basically, at-least-so-many-bits integers, pointers, and malloc().

Please answer this question:
Why is vector not implemented using vector? (I'm serious.)

OK I get your point, and you are right. These things would be nice to
have in C++, and I think it is possible to have them just by introducing
new keywords in the language, without breaking backwards compatibility.
I do not know why there is no proposal for these.
The fastest possible element access in C++ is dereferencing a pointer.
The fastest possible element access in STL/C++ is varying with container
and method.

Compare

type Floor_Number is -2 .. 52;
-- sky scraper

type Door_Count is array(Floor_Number) of Natural;

versus

typedef char Floor_Number;
typedef std::map<Floor_Number, unsigned int> Door_Count;

char does not feel well, one could use short but probably will use int.
We are discussing fastest access, and type based indexing.

I can't understand why your code has faster access (I assume you mean
run-time efficiency).

So my question again, what does it take, in C++, to replace
Floor_Number as typedefed above with something that matches
the given building's floors exactly?

I assume a vector that permits defining negative indices, and this is
easy to be defined. However I may assume that since no such vector
container is provided (even third-party), I may assume that either it is
not considered as needed, or it is believed that maps and hash_maps can
do the job.
To give another example, .NET does not provide such an array container
either, in its own containers collection. So why such a mainstream
framework does not provide an array type with negative indexing either?
This is not some kind of general proof, but for me it is an indication.
Again, I agree that boundary checking etc are useful and should be added
in C++ perhaps with additional keywords.

The point is, how does a language help you writing
correct and efficient programs. C++ the language doesn't
have fixed size built in arrays. In some problem domains,
fixed size arrays are very useful, if not essential.

This is why many programming languages have them.


Just to be technically accurate. C++ has fixed size built in arrays. It
doesn't provide range checking for them though.
int array[4];

is a fixed size, stack based, built in array.
Fixed size in the heap:

int *parray= new int[4];
Also, standard library containers with fixed size are valarray and bitset.

--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 23 '05 #587
Martin Dowie wrote:
It will have multiple inheritance of interfaces (a la Java) in
Ada2005 - is that enough?

For application programming only, it is usually enough. I am not sure if
in library writing it is enough though.

--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 23 '05 #588
ad******@sbcglobal.net wrote:
OK. I read your C++ example with care and interest.
Then I compared it, once again, with the example I wrote.

I wonder if you truly think the two examples are equlivalent
in all respects. I must confess that, if the C++ example
were an accurate representation of how one would solve
this problem in that language, I would abandon C++ for
all time.

A key goal of Ada is to produce readable code, not simply
writeable solutions in cryptic code. Who, upon encountering
the C++ example in your post, would be able to quickly
apprehend the meaning, the intent, or the result of this
code?

Believe it or not, I do not understand most of Ada code, apart from some
Pascal-like constructs here and there. :-)

--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 23 '05 #589
Martin Dowie wrote:
That 'problem' isn't unique to Ada - I can't think of another
language that *does* define a pre-processor.

And if you like a preprocessor - just use one! You can always write
a makefile/.bat/.com/<whatever> to invoke the preprocessor before the
compiler is called. GNAT comes with an Ada-centric preprocessor but
there is nothing to stop you using the 'C' one.

Here is an interesting link BTW:

http://boost-consulting.com/tmpbook/preprocessor.html

--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 23 '05 #590
Georg Bauhaus wrote:
µC++ adds concurrency support to the C++ type system, at a somewhat
lower level of abstraction than Ada.

Concurrency is a hot issue, currently considered system-specific in C++.
It will be included in C++0x (I hope the right choices will be made).

There is also OpenMP of course (http://www.openmp.org).

Still, µC+++ reimports the weaknesses of the precursor languages.
Sad, but successful because of mass momentum.

I keep hearing about this µC++, may you provide a relevant link? I
couldn't find anything in google, is the first character a Greek
character? It appears as the Greek character 'm' in my screen.

--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 23 '05 #591
Jerry Coffin wrote:
Some areas are somewhat more questionable -- calling a class a "tagged
record" is clearly a mistake, but it's open to question whether it
should be classified under poor expression of the concept, or just
general idiocy.
http://groups-beta.google.com/group/...536ae8243e253c

class type T is ...

instead of

type T is tagged ...
In C++ you can throw an arbitrary type of object with an arbitrary
value.


How well does this style of passing information work across thread
boundaries? (Not debating the usefulness of the mechanism. Although
I think it deserves to be separated from exception handling.)

Georg
Jul 23 '05 #592
In article <11*********************@z14g2000cwz.googlegroups. com>, "Jerry Coffin" <jc*****@taeus.com> writes:
Some of the cited cases provide checks that are free in terms of
run-time, but run-time is hardly the major cost in most software.
Really ?

Even programs I write for my own personal use are run _many_ more times
than they are compiled. Personally, I often spend compile time thinking
some more about the problem, sometimes to good advantage :-)
Just for one obvious example, Ada doesn't provide an easy way to
express/do most of the things one can do with the C or C++
preprocessor.
It does not provide a preprocessor, for safety reasons.

But what programming step (as distinguished from construction trick)
can only be performed from a preprocessor ?
Some areas are somewhat more questionable -- calling a class a "tagged
record" is clearly a mistake, but it's open to question whether it
should be classified under poor expression of the concept, or just
general idiocy.


I see no mistake. Is it possible your background in Pascal is inadequate
and overwhelmed by your background in C* languages.

Jul 23 '05 #593
Dr. Adrian Wrigley wrote:
And you can do really handy stuff passing arrays not indexed from 0,
and accessing the attributes:

-- No particular purpose but to demo
type MyString is array (Integer range <>) of Integer;

procedure UpdateString (Blob : in out MyString; K : Integer) is
begin

if Blob'Length = 0 then
return;
elsif Blob'Length = 1 then
Blob (Blob'First) := Blob (Blob'First) + K;
return;
else
UpdateString (Blob (Blob'First .. Blob'First+Blob'Length/2-1), 19);
UpdateString (Blob (Blob'First+Blob'Length/2 .. Blob'Last), 27);
return;
end if;

end UpdateString;
...
UpdateString (Fred (10 .. 19), 0);

If you provide some explanations, I will give you the C++ equivalent.

What does this mean?

Blob : in out MyString

--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 23 '05 #594

Jerry Coffin wrote:

char[] and wchar_t[] are arrays, not strings.
Well, that's true of Ada's String and Wide_String.

C++ really only has one
string type: std::basic_string. std::string and std::wstring are not
types of their own at all, but simply typedefs as:

typedef std::basic_string<char> string;
typedef std::basic_string<wchar_t> wstring;
That's more or less what type Unbounded_String is, too.

There appears to be a difference in terminology. I and every other
developer I know refers to type const char* as a string. (For example,
H&S Ch. 13 is titled "String Processing.")

In any event, that's probably how the OP was using the term when he
said "Ada has 5 string types." If you don't regard arrays as members
of the class of string types, then you can reduce Ada's count
accordingly.

In addition, one of the major arguments the Ada fans have used here is that Ada's strings are built-in, NOT added as a class like in C++. If
C++ had been designed from the beginning with a string class, the
array-based "stuff" probably wouldn't exist at all.
I don't see what difference it makes whether the type is built-in or
not. What's wrong with an added class? Perhaps they were refering to
the fact that you can declare array objects (strings) with non-static
bounds on the stack (since clearly Unbounded_String is not a built-in
type).

BTW, in case anybody really cares, yes I apply the same standard to
C++: while its string handling facilities are fewer and IMO better than Ada's, they're still far short of perfect.


I prefer string handling in C++ too, but not being able to declare an
array (on the stack) with non-static bounds is a real pain sometimes
(although std::string mostly compensates for this). I agree that Ada's
string handling facilities aren't as nice, but they do get the job
done.

Jul 23 '05 #595
Ioannis Vranos wrote:


I keep hearing about this µC++, may you provide a relevant link? I
couldn't find anything in google, is the first character a Greek
character? It appears as the Greek character 'm' in my screen.

http://plg.uwaterloo.ca/~usystem/

Seems like µ, or &mu;, is not a good search term. Try "uSystem".
Jul 23 '05 #596
Georg Bauhaus wrote:
In C++ you can throw an arbitrary type of object with an arbitrary
value.

How well does this style of passing information work across thread
boundaries?

Do you mean throwing an exception in one thread and catch it in another?

(Not debating the usefulness of the mechanism. Although
I think it deserves to be separated from exception handling.)


Actually it is bot separated, in C++ all standard library exception
classes are (ordinary classes) derived from the base class exception
defined in <exception>.

--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 23 '05 #597
REH

"Ioannis Vranos" <iv*@remove.this.grad.com> wrote in message
news:1111613984.430545@athnrd02...
What does this mean?

Blob : in out MyString

It about the same as a non-constant reference.
Jul 23 '05 #598
Ioannis Vranos wrote:

The fastest possible element access in C++ is dereferencing a pointer.
The fastest possible element access in STL/C++ is varying with container
and method.

Compare

type Floor_Number is -2 .. 52;
-- sky scraper

type Door_Count is array(Floor_Number) of Natural;

versus

typedef char Floor_Number;
typedef std::map<Floor_Number, unsigned int> Door_Count;

I can't understand why your code has faster access (I assume you mean
run-time efficiency).
Door_Count array access is faster because while it acts like
std::map<Floor_Number, unsigned int>, it is really an array.

Omitting the association of the indexing number numbers (-2 .. 52) with
the floors for the moment, these tests should demonstrate:

#include <map>
#include <hash_map> // GNU: #include <ext/hash_map>, __gnu_cxx::hash_map
#include <valarray>
#include <vector>

#define M 55 // array size
#define N 10000 // assigments
#define R 5000 // runs
struct Test { // compare random access to keyed access

void arrays() {
int a[M];

for (int k = 0; k < N; ++k)
a[k % M] = k;
}

void valarrays() {
std::valarray<int> a(M);

for (int k = 0; k < N; ++k)
a[k % M] = k;
}

void vectors() {
std::vector<int> a(M);

for (int k = 0; k < N; ++k)
a[k % M] = k;
}

void maps() {
std::map<int, int> a;

for (int k = 0; k < N; ++k)
a[k % M] = k;
}

void hash_maps() {
std::hash_map<int, int> a;

for (int k = 0; k < N; ++k)
a[k % M] = k;
}

};

int main()
{
Test t;

for (int run = 0; run < R; ++run)
t.arrays();
// t.valarrays();
// t.vectors();
// t.maps();
// t.hash_maps();

return 0;
}
To give another example, .NET does not provide such an array container
either, in its own containers collection. So why such a mainstream
framework does not provide an array type with negative indexing either?
C# does provide fixing arrays.

I think we can't buy high speed computing components from the
producers of .NET. However, Fortran for .NET is available. (Doesn't mean
the producers of libraries will use non-default index value in Fortran code.)
So is APL.

This is not some kind of general proof, but for me it is an indication.
Again, I agree that boundary checking etc are useful and should be added
in C++ perhaps with additional keywords.
Have you had a look at D?

Just to be technically accurate. C++ has fixed size built in arrays. It
doesn't provide range checking for them though.


OK. And lets see what happens when the C99 arrays will be adopted.

Georg
Jul 23 '05 #599
Larry Kilgallen wrote:
In article <11*********************@z14g2000cwz.googlegroups. com>, "Jerry Coffin" <jc*****@taeus.com> writes:
Some of the cited cases provide checks that are free in terms of
run-time, but run-time is hardly the major cost in most software.
Really ?

Even programs I write for my own personal use are run _many_ more
times than they are compiled. Personally, I often spend compile
time thinking some more about the problem, sometimes to good
advantage :-)


Being compiled isn't the major cost either.

For an awful lot of software, being run multitudes of times doesn't
make speed important -- interactive software (for one example) has
something on the order of really soft real-time requirements. I.e. too
slow is mildly annoying, but any response time under 100 ms or so
qualifies as "instant", and after that making it 100 or even a million
times faster rarely accomplishes much.
Just for one obvious example, Ada doesn't provide an easy way to
express/do most of the things one can do with the C or C++
preprocessor.


It does not provide a preprocessor, for safety reasons.


Look again at the wording -- I spoke in terms of the capabilities that
C happens to provide as what's generally called the preprocessor. I
could say "phases 1 through 6 of translation" if I wanted to be more
formal, but it's utterly irrelevant.

Regardless of the wording, however, I think this is (mostly) a
red-herring. What do you consider unsafe about (for example) some chunk
of code being compiled only when I want it to be? If I really believe
in the compiler's optimizer, I can already do things like "if False" in
Ada, and that code clearly won't ever execute. It just happens that C
and C++ provide a simple and practical method of doing the same things
in a way that's easy to externally control.
But what programming step (as distinguished from construction trick)
can only be performed from a preprocessor ?
Attempting to separate programming from constructing (a program) seems
to me a strong indication that you don't really know much of what
you're talking about. Regardless of this, however, the fact is that
even in Ada people who have a preprocessor available (e.g. with GNAT)
frequently find it extremely useful -- but using it renders the code
completely non-portable.
Some areas are somewhat more questionable -- calling a class a
"tagged record" is clearly a mistake, but it's open to question
whether it should be classified under poor expression of the
concept, or just general idiocy.


I see no mistake.


There is none so blind as he who will not see. The biggest problem is
that "tagged record" is a low-level description -- i.e. it's about the
implementation, not the real concept. A secondary problem is that in
other Pascal-family languages (e.g. Pascal, Modula II, Modula 3 and
probably Oberon), a "tag" is the distinguishing characteristics of a
variant record, having nothing to do with object orientation.
Is it possible your background in Pascal is inadequate
and overwhelmed by your background in C* languages.


Pascal has records, but not "tagged records". I don't believe Modula
II, Modula 3 or Oberon uses such poor terminology either. I don't see
how background in C signifies at all, since it doesn't use "record",
"tagged record" or "class" at all. I suppose one could point out that C
uses names that reasonably accurately reflect what's being discussed,
but I have a hard time calling that a bad thing...

OTOH, if you look through a language-neutral book on object oriented
programming, you'll "class" used to name a rather general concept quite
routinely. By contrast, I've yet to see "tagged record" used to
describe anything except the syntax of Ada 95.

--
Later,
Jerry.

The universe is a figment of its own imagination.

Jul 23 '05 #600

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

20
by: Mediocre Person | last post by:
Well, after years of teaching grade 12 students c++, I've decided to make a switch to Python. Why? * interactive mode for learning * less fussing with edit - compile - link - run - debug -...
14
by: Gabriel Zachmann | last post by:
This post is not strictly Python-specific, still I would like to learn other university teachers' opinion. Currently, I'm teaching "introduction to OO programming" at the undergrad level. My...
3
by: andy_irl | last post by:
Hi there I have been asked to teach HTML to a group in our local village community. It is nothing too serious, just a community development grant aided scheme. It will be a 10 week course of two...
12
by: Pierre Senellart | last post by:
I am going to teach a basic Web design course (fundamentals of HTML/CSS, plus some basic client-side (JavaScript) and server-side (PHP, perhaps XSLT) scripting). Most of the students do not have...
16
by: msnews.microsoft.com | last post by:
I am teaching C# to my 11 year old child. One challenge is that all the C# books I own and that I have seen in bookstores are full of language that is not easily comprehended by a student at that...
24
by: Richard Aubin | last post by:
I'm really new to vb.net programming and programming in general. I would like to teach myself on how to program effectively and I have the financial and time resources to do so. Can I anyone...
0
by: e.expelliarmus | last post by:
check this out buddies. kool website for: * hacking and anti hacking tricks * anti hackng tricks. * registry tweaks * orkut tricks * small virus * computer tricks and loads of different...
1
by: JosAH | last post by:
Greetings, Introduction This week's tip describes a few old tricks that are almost forgotten by most people around here. Sometimes there's no need for these tricks anymore because processors...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.