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

  • Thread starter Turamnvia Suouriviaskimatta
  • Start date
G

Georg Bauhaus

Try again. Show me how sizeof(z) != 8 in Ada.

I'm not sure I understand. On an x86 system,

type Tiny is range 0 .. 31;
-- stored in an 8 bits register unless I demand otherwise

Type TP is access all Tiny;
for TP'Size use 32; -- in bits.

Ask for more bits for the pointer if you like. E.g.,

for TP'Size use 128;

In this case you get a compiler warning about unused bits. Then,
without any optimization, I get diffs of this sort, reflecting
the difference in the sizes of the pointer types TP:

< subl $8, %esp
---
subl $40, %esp
32,33c32,33
< leal -1(%ebp), %eax
< movl %eax, -8(%ebp)
---
 
G

Georg Bauhaus

CTips said:
Nope, not z = p[0], z = p; Z is a _pointer_ to int, not an int.

Well, yes. Nothing stops you from passing a pointer to an int
in Ada, in both read-only and read-write mode.
And you can of course have pointers to arbitraty locations but you
have to use language to express this fact, using for example

for X'Adress use ...;

Or use the adressing types and operations in the System hierarchy.

You can also use any bit pattern to represent anything as long as
you explicitly ask for a new interpretation. Isn't this slightly more
permissive than what can be expressed using reinterpret_cast in C++?

Also, Unchecked_Conversion is neither casting, nor the usual type
conversion.
If I wanted the bits of a 32 bits float of value 3.14 to stand for an
integer, type conversion will give 3, an instance of Unchecked_Conversion
will give 1078523331.

Georg
 
I

Ioannis Vranos

Falk said:
Furthermore, the implementer of "whatever_type" should consider to
put the specialisation of "swap" into the "std" namespace, which
is possible by § 17.4.3.1/1 of the Standard.

Too tricky, can become bad habit.
 
I

Ioannis Vranos

John said:
What????????????????????????????????????????????????? Assembly language?
powerful? If you decide to write a X GUI interface in assembly, I'll
check in on you in 20 years to see how your doing.... Higher level
languages handle broader abstract concepts better than low level
languages. Assembly is great if you are optimizing device drivers or
banging bits at the hardware register level...not good at implementing
scientific algorithms, GUIs, databases, etc. There are thousands of
reasearch papers that extol the problems of assembly language approach
to things, and yes, there are places and reasons to use it, but
classifying it as a 'higher level language' and something more powerful
is incorrect....


Actually I think if you use the platform's APIs it is taking much less.
For example I think one may use Win32 API with assembly.


Also the assembly that I have primarily in mind is the one of .NET.


..NET is a CLI VM and here is a book about .NET's (CLI) VM assembly language:

http://www.amazon.com/exec/obidos/t...f=sr_1_7/102-2992266-3703320?v=glance&s=books



CLI assembly language is defined in the freely available CLI standard,
so you can view in the specification how it looks like:

http://www.ecma-international.org/publications/standards/Ecma-335.htm
 
I

Ioannis Vranos

John said:
Exactly - because not every programmer is well organized to keep all the
nuances in their head, and observe them when coding. Furthermore, when
components are integrated and one component talks to another is when the
big debugging problems surface. One has to look at the
history/motivation of Ada development versus that of C/C++...Ada
certified compilers and tools strictly enforce the semantics of the
language. It has been my experience that there is a lot of variability
in C/C++ compilers in how through language semantics are adhered to.


There is no variability concerning ISO C++ features these days.


A question: With .NET facilities, when one performs an invalid operation
like accessing an array out of its bounds an exception is thrown and the
program terminates indicating what was the problem.


This is the kind of run-time safety Ada provides or is there something else?


int main()
{
using namespace System;

array<int> ^someArray= {1,2,3,4,5,6,7,8,9,0};

someArray[10]= 7;
}


C:\c>temp

Unhandled Exception: System.IndexOutOfRangeException: Index was outside
the bounds of the array.
at main()

C:\c>
 
I

Ioannis Vranos

Dr. Adrian Wrigley said:
This is is well known.

I was asking for my misconception on what *C++ was designed for* to
be dispelled.


It began as "C with classes", but this does not mean "it was designed
for" that only.
 
I

Ioannis Vranos

Pascal said:
For example (if you ask):

type Table is array (1 .. 10) of Integer;

Data : Table;

for K in Data'Range loop
if Data (K) = 1 then
...
end if;
end loop;

There is no need to check K validity inside the loop as "Data (K)" is always
correct by definition (K in Data'Range). Just an example.


Pascal, this looks like Pascal.


The C++ equivalent:


#include <vector>

// ...


using namespace std;

vector<int> Data(10);

for(vector<int>::size_type i=0; i<Data.size(); ++i)
{
if (Data== 1)
{
// ...
}
}
 
I

Ioannis Vranos

Larry said:
Nobody has come up with something that cannot be expressed in Ada (or
in C++ for that matter). Ada code is more verbose, on the grounds that
code is read more often than it is written (or at least it should be).


Don't confuse verbose with being comprehensible. Myself that do not know
Ada, I cannot understand much when I see Ada code, apart from some
Pascal style declarations of variables, procedures and records, and this
because I have used Pascal. :)
 
J

Jim Rogers

Peter said:
Actually, a close reading of the thread should have made it clear
that the additional safety is indeed "free".

Free? Well, lets look at one particular issue: pointers to arbitrary
locations. In C, its a common idiom to do the following:
foo(int * p)
{
int * z;
for( i ... ) {
... p...;
}
z = p;
}

...
foo( &x[lo] );
...

Now, how can *any* language check to see that p is within bounds?


This is one of the unsafe idioms in C.
The fact that you can declare a formal parameter as a pointer and then
use that parameter as an array is unsafe. This can only be done
safely if you either assume the existence of meta-data in the array
to indicate the end of usable data (as in the \0 at the end of a string),
or you must pass a second parameter telling you how long the array should
be. Of course, that second parameter must be handled carefully. Improper
values in the second parameter will cause you to skip array components
or will create a bounds violation. Array bounds violations have for years
been one of the most frequent C programming errors, and a boon to
virus writers.

Ada arrays are not so closely related to pointers.
One can create an access type that "points" to an array.


type int_array is array(1..10) of integer;
type int_ptr is access int_array;

Note that int_ptr is not a pointer to an integer,
but a pointer to an array of integers.

procedure foo(p : int_ptr) is
begin
for I in p.all'range loop
... p(I)...
end loop;
end foo;

ip : int_ptr := new int_array;

foo(ip);

All this works without a problem in Ada.

Jim Rogers
 
J

Jerry Coffin

Martin Dowie wrote:

[ ... ]
It's an opinion /nearly/ shared with P. J. Plauger of the ANSI-C
committee (and Dinkumware) - only I believe he quoted 100 thousand
lines as the point at which you should be using Ada. :)

Which is utterly irrelevant to the original point, which was about
stating opinions as facts, not about who holds what opinion.

I am curious though: how do you make a meaningful comparison? If I
write something that takes only two thousand lines of SQL, it's almost
certain to take _well_ over that 100 thousand lines of Ada and might
well be closer to a million.

To me, using Ada in that situation sounds insane. Richard Reihle might
think it's the right thing to do, but I'm fairly certain that P.J.
Plaugar would disagree. I certainly don't have to think very hard to
guess at what my boss would say.
 
J

Jerry Coffin

Dr. Adrian Wrigley wrote:

[ ... ]
Isn't there some confusion here?

Surely the "aliasing" issue (ignored by C++ completely(?)) is largely
independent if the "reinterpret_cast"/"Unchecked_Conversion" issue?

Yes -- he started by mentioning aliasing, but mostly seemed to be
talking about type punning, so that was what I replied to. The
discussion centered around safety, which is essentially orthogonal to
aliasing.
The C++ programmer uses aliasing routinely and without thinking.

Aliasing is used frequently in C++, that much is true. IMO, the claim
that it's done "without thinking" is nothing more or less than flame
bait. I think you're capable of better.
Ada makes the aliasing possibility explicit when necessary, but
prohibits it otherwise.

Aliasing is almost certainly more common in C++, but ultimately it only
ever happens explicitly in either language. In fact, I think "explicit"
is virtually meaningless in discussing a programming language -- the
processor is not an intelligent being that makes decisions on its own
unless explicitly directed. As such, nothing in code is really
implicit. What most people call "implicit" is simply the rules of the
language doing their job. Even those who push explicitness as a virtue
rarely do things like parenthesizing a+(b*c). Even those who argue most
strongly for explicitness generally agree that this would be silly, at
least in "obvious" cases like the one above.

The "implicit" behavior I've seen Ada programmers complain about in C++
is equally codified in the rules of the language, and the fact that Ada
programmers think it's somehow implicit mostly just reflects the fact
that they don't know those rules. That's fine, but condemning the
language simply because they don't know it is much less so.
If we're talking about the "reinterpret_cast" issue, it is
essentially identical in Ada.

....and this is what actually affects safety. Aliasing mostly just makes
it more difficult to generate efficient code. Despite this, most claims
that C and/or C++ produce particularly poor code show little more than
defects in the testing.
 
C

CTips

Dmitry said:
Ask your compiler vendor. Though it wouldn't be necessarily polling. Also
usually protected objects are not used for so utterly fine-grained mutual
exclusion/locking. Atomic integer increment is normally just a small part
of some larger (but not lengthy) operation For example, placing something
in a queue.

Umm...can be done without locking. See wait-free/lock-free algorithms.

Therefore spinning for a lock (which probably would be the
implementation) will likely be less expensive than some tricky guards
attached to each and every instruction.

You *REALLY* should see what can be done with lwlock/stwcond. You'll be
suprised how cheap synchronization can be.
Note also that at such a low level
it would be very difficult if possible to maintain data consistency.
Compiler simply does not know what is related to what and will try to cope
with the worst case scenario.

So, what escapes does the language provide to let you do this? None?
Protected types in Ada are to describe this
sort of semantics. So in the end atomic integers are pretty useless, no
matter how efficient they could be implemented.

That is one reason *NOT* to learn Ada; it restricts both choices and
thinking.
 
M

Martin Dowie

Ioannis said:
There is no variability concerning ISO C++ features these days.

You've been lucky then... ;-)

The last time I tried to port any C++ was between VxWorks and Borland...
complete nightmare! And that wasn't so long ago...

But YMMV.

Cheers

-- Martin
 
M

Martin Dowie

Jerry said:
Martin Dowie wrote:

[ ... ]

It's an opinion /nearly/ shared with P. J. Plauger of the ANSI-C
committee (and Dinkumware) - only I believe he quoted 100 thousand
lines as the point at which you should be using Ada. :)


Which is utterly irrelevant to the original point, which was about
stating opinions as facts, not about who holds what opinion.

Hey! I did add a smiley! I just thought it was an opinion from a
reputable source that tied in with the post. :) :)

I am curious though: how do you make a meaningful comparison? If I
write something that takes only two thousand lines of SQL, it's almost
certain to take _well_ over that 100 thousand lines of Ada and might
well be closer to a million.

To me, using Ada in that situation sounds insane. Richard Reihle might
think it's the right thing to do, but I'm fairly certain that P.J.
Plaugar would disagree.

Would I be allowed to use embedded SQL in the Ada code (GNADE)? Or a
binding to Postgres or MySQL (APQ) or similar (ODBC)?

I certainly don't have to think very hard to guess at what my boss would say.

Sorry, I don't know your boss.

Cheers

-- Martin
 
P

Pascal Obry

Ioannis Vranos said:
Pascal, this looks like Pascal.
Agreed.

The C++ equivalent:


#include <vector>

// ...


using namespace std;

vector<int> Data(10);

for(vector<int>::size_type i=0; i<Data.size(); ++i)
{
if (Data== 1)


And no C++ compiler will check that Data is valid. That's the point. If you
add the check explicitly no C++ compiler will be able to remove it. In the Ada
case the compiler knows lot more about the program and can decide to remove
the check if it knows that the index will never be outside the object
range. This is always the case for:

for K in Data'Range loop
... Data(k)...

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
 
D

Dmitry A. Kazakov

Umm...can be done without locking. See wait-free/lock-free algorithms.

Honestly, I don't care. You know, I am not developing integer incrementers,
am developing software...
You *REALLY* should see what can be done with lwlock/stwcond. You'll be
suprised how cheap synchronization can be.


So, what escapes does the language provide to let you do this? None?

As I said it provides protected objects, which in a real-life concurrent
application will be more efficient, far more safe and maintainable, and yet
portable as compared with your inlined assembler in C. I saw much too much
of embedded C code programmed in the style you seem to favor. The main
problem with such code, is that it's a garbage which simply does not
fulfill the requirements, including the time constraints as well.

BTW, if you are so eager to have assembly code insertions, then Ada does
have them. See ARM 13.8.
That is one reason *NOT* to learn Ada; it restricts both choices and
thinking.

How does Ada restrict choices? As for thinking that's up to you.
 
P

Pascal Obry

CTips said:
Will that generate:
L0:
lwlock temp,&Value
add temp,temp,1
stwcond temp,&Value
if( failed ) goto L0;
or will it generate something much more heavy-weight.

BTW, do you know a C compiler that generates such code ? Why Ada should be
different ? I think there is no way to tell compilers in any language about
somthing like that. I doubt that even the Ada "pragma Atomic" can be used to
generate such code. And as others have posted it is always possible to use
inline assembly. I don't think it is a good idea in the long term but maybe
for very specialized applications...

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
 
D

Dmitry A. Kazakov

This is one of the unsafe idioms in C.
The fact that you can declare a formal parameter as a pointer and then
use that parameter as an array is unsafe.

It is also unusable with small and packed data types in which case the
array elements may have no valid machine addresses.

The bottom line: array is an interface.
 
I

Ioannis Vranos

Martin said:
You've been lucky then... ;-)

The last time I tried to port any C++ was between VxWorks and Borland...
complete nightmare! And that wasn't so long ago...

But YMMV.


The first C++ standard has been relatively recent (1998). In the
contrary Ada's has been probably around since the '80s. :)


So it makes some sense that only the last couple of years we are getting
 
P

Peter Hermann

In comp.lang.ada Jerry Coffin said:
rarely do things like parenthesizing a+(b*c). Even those who argue most
strongly for explicitness generally agree that this would be silly, at
least in "obvious" cases like the one above.

No, it is not silly.
It shows professionality, even when not in doubt.
There is no compelling reason to learn those many priority rules
for Ada expressions to achieve secondary bulk knowledge.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,206
Messages
2,571,069
Members
47,675
Latest member
RollandKna

Latest Threads

Top