comp.lang.ada
 help / color / mirror / Atom feed
* Interfacing Ada95 programs to each other and to C and C++
@ 1998-05-10  0:00 Joe Gwinn
  1998-05-10  0:00 ` Robert Dewar
  0 siblings, 1 reply; 2+ messages in thread
From: Joe Gwinn @ 1998-05-10  0:00 UTC (permalink / raw)



This is my current list of issues in interfacing Ada95 programs to each
other and to C and C++ programs.  Some of these issues have been mentioned
in prior postings, but are repeated here for completeness.  We are still
integrating, so not all issues have been uncovered and solved.


The prime requirement is not just successful interfacing, it's bulletproof
target-independent, compiler-independent portable interfacing.  There are
many solutions that will work for one or another specific pair of
compilers and/or languages, but very few solutions will work for any or
even most pairs.  Why is this important?  Because with the short lifetimes
of current compiler versions and COTS targets, we will port our code many
times in the development and life of the code, and it's too expensive and
error prone if the interfaces (many having hundreds of message types) fall
apart every time something is changed.

There are two related interface areas, procedure call conventions and
handling of data and data structures passed through the procedure call
interface, and the passing of messages (moveable data structures) between
programs in various languages via some kind of communications system.  In
procedure call issues, at least the target processor is the same.


1.  Alignment clauses do not necessarily govern dynamic objects (those
declared in procedures rather than the main).  Things that must be aligned
must thus be handled at the "main" level, or alignment commands will be
ignored.  This matters for two reasons.  First, many realtime
communications systems require specific data alignments.  Likewise, I/O
drivers and hardware.  Second, different compilers, especially if targeted
on different processors, often pad the elements of data structures
differently.  If one makes all fields 32-bit items, padding is lass
variable.  

2.  Rep specs cannot be used on enumeration types (because many compilers
generate tremendous amounts of code to handle all possible cases, however
unlikely), so one cannot use enumeration types in messages.  

3.  If an integer field in a record is a subrange type, Ada will tend to
use the smallest kind of integer that will hold the field, overriding any
rep specs to the contrary.  Other languages and compilers, especially on
different targets, may chose different kinds of integer and different
paddings.  This too can be solved by making all integers 32-bit, and
dropping any use of subranges (and the attendant range checks).  

4.  There may also be a endian problem; we haven't completely sorted this
out yet, but we have cases where the wrong end of a 32-bit integer is kept
as a packed subrange.  This may just be a bug. 

5.  Floating-point fields, 32-bit and 64-bit IEEE 754, have caused no
problems so far, even between machines of differing type, something of a
surprise.  Floating point is more complex than integers, and some machines
have somewhat different endian behaviour for floats than for integers.


These are the causes of most problems we have seen so far.  Simple human
error has accounted for the rest.


Joe Gwinn




^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Interfacing Ada95 programs to each other and to C and C++
  1998-05-10  0:00 Interfacing Ada95 programs to each other and to C and C++ Joe Gwinn
@ 1998-05-10  0:00 ` Robert Dewar
  0 siblings, 0 replies; 2+ messages in thread
From: Robert Dewar @ 1998-05-10  0:00 UTC (permalink / raw)



Joe said:

<<1.  Alignment clauses do not necessarily govern dynamic objects (those
  declared in procedures rather than the main).  Things that must be aligned
  must thus be handled at the "main" level, or alignment commands will be
  ignored.  This matters for two reasons.  First, many realtime
  communications systems require specific data alignments.  Likewise, I/O
  drivers and hardware.  Second, different compilers, especially if targeted
  on different processors, often pad the elements of data structures
  differently.  If one makes all fields 32-bit items, padding is lass
  variable.>>

This needs more detail. Certainly if an alignment is specified for a type,
this applies to both global and local objects, and indeed to *all* objects
of the type, unless specifically overridden (e.g. by a component clause).
With the detail above, the most likely suspicion is that this is a compiler
problem. Certainly the Ada 95 RM (and GNAT!) guarantees that the alignment
of an object of a type always be consistent with the declared alignment.

As to the padding, see the discussion of point 3

<<2.  Rep specs cannot be used on enumeration types (because many compilers
  generate tremendous amounts of code to handle all possible cases, however
  unlikely), so one cannot use enumeration types in messages.>>

Again, more details are needed. We know from a previous thread on CLA that
one compiler (not GNAT!) mishandled the case where a (completely unnecessary
and redundant) rep clause was given confirming the default representation
(0,1,2,....) If this is what Joe is referring to, then this is certainly
not a language issue, but merely a glitch in a particular compiler (since
corrected as far as I know). 

If we are really talking about a non-default case, then this complaint
seems a bit misguided. In Ada 95, there are two ways of mapping an 
external discrete type that has a small set of non-contiguous values.

  a) Define an integer type with a set of numeric constants. This
     corresponds exactly to the C style and semantics, and is usually
     preferable.

  b) Define an enumeration type with an enumeration representation
     clause. This will generate extra code only if operations like
     pos and rep are used which clearly require this code. 

I certainly see that programmers might use this feature without realizing
the inevitable inefficiencies that result from the use of such types, but
this is an error on the part of the programmer. This is a feature that
(like any other feature) should only be used if it is needed. I certainly
have trouble understanding this as a complaint about Ada 95. If you don't
like the (unavoidable) additional code for use of e.g. pos or array
subscripting, then don't use the feature!

<<3.  If an integer field in a record is a subrange type, Ada will tend to
  use the smallest kind of integer that will hold the field, overriding any
  rep specs to the contrary.  Other languages and compilers, especially on
  different targets, may chose different kinds of integer and different
  paddings.  This too can be solved by making all integers 32-bit, and
  dropping any use of subranges (and the attendant range checks).>>

What Joe is talking about here is that a record like

   type x is record
      a : integer;
      b : integer range 1 .. 10;
      c : integer range 1 .. 10;
      d : integer range 1 .. 10;
      e : integer range 1 .. 10;
   end record

may be represented differently from

   struct x {
      int a;
      int b;
      int c;
      int d;
      int e;
   };

since an Ada compiler is free to (but not required to) allocate only
one byte for b,c,d,e (or even only 4 bits). In large legacy programs,
we have often found assumptions about the layout of such records, and
in fact GNAT always allocates the same space for subtypes as for the
parent type to minimize disruption in such programs.

HOWEVER: this is NOT a complaint about Ada 95, it is a complaint about
incompetent Ada programmers. No doubt Joe will complain that only someone
with a PhD in computer science could be expected to know, but it is
absolutely clear that if you write a record declaration like the above
one, you are QUITE EXPLICITLY saying that you do not care how the record
is laid out.

If you care how a record is layed out, you have two alternatives:

  1. Use only types in the record which have a direct correspondence in
  the interfaced language (e.g. C.Interfaces.int) and then use pragma
  Convention (C).

  2. Use an explicit record representation clause with component clauses
  that layout the record as required.

It sounds like Joe was running into the problem of incorrectly written
programs which made unwarranted assumptions about how records are laid
out. Portable code does not come automatically, and an incompetent
programmer can easily make these kind of bad assumptions, but I don't
see it as a legitimate complaint about the language.

Joe said that "rep specs" to the contrary were "overridden". I assume
he means rep clauses (rep specs is a popular though incorrect term). I
am not sure what particular rep clause he is referring to. Certainly
the only valid rep clauses for solving this problem are, as described
above pragma Convention (actually a rep pragma) or a record representation
clause. Note that in the absence of one or other of these two kinds of
rep items, a compiler is free even to modify the *order* of the fields
in a record, or to store the record in non-contiguous chunks.

Often what happens in large programs is that programmers flail around till
they get something that happens to work with the particular version of the
compiler they are using. This is NOT the way to write portable code.

No one is claiming that code in Ada is guaranteed to be portable, and this
is especially true of incorrectly written interfacing code. The claim is
that Ada 95, uniquely, provides facilities which, if used properly by a
competent programmer, can indeed guarantee portable interfacing.
interfacing does not come for free, you have to write the program 


<<4.  There may also be a endian problem; we haven't completely sorted this
  out yet, but we have cases where the wrong end of a 32-bit integer is kept
  as a packed subrange.  This may just be a bug.>>

Clearly not much to respond to here. Endian issues should not arise in
interfacing between Ada and (e.g.) C on a given machine.


<<5.  Floating-point fields, 32-bit and 64-bit IEEE 754, have caused no
  problems so far, even between machines of differing type, something of a
  surprise.  Floating point is more complex than integers, and some machines
  have somewhat different endian behaviour for floats than for integers.>>

Ah! Wait a moment! Absolutely NOTHING in Ada suggests that the problem of
interfacing between different machines is solved. And most certainly if
you transmit binary fpt data between a big-endian and little-endian machine
it certainly will not work. What GNAT does to solve this problem is to 
provide a version of the stream attribute support that uses XDR, which
eliminates problems arising from different representations on different
machines. This has nothing to do with interfacing from Ada to other
languages.


<<These are the causes of most problems we have seen so far.  Simple human
  error has accounted for the rest.>>

I rather suspect that most if not all of the problems referred to above
are also the result of human error in not using the features of Ada 95
correctly (or human error in implementing the particular compiler that
Joe is using. I am not sure which compiler this is, but from the complaints,
I am pretty sure it is not GNAT. In any case, it is important to distinguish
between:

   1. Fundamental problems in the design of the language
   2. Errors in use of the language by programmers
   3. Implementation errors in the compiler

I certainly do not claim that no errors in categories 2 and 3 exist, but
I fail to find any evidence at all in Joe's list that there are any
problems in category 1. I believe that Joe's goal of bulletproof portable
interfacing with C can indeed be achieved, and have yet to see evidence
that this is not the case. Certainly we talk all the time to GNAT
customers who have achieved this goal using Ada 95.

Robert Dewar





^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~1998-05-10  0:00 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1998-05-10  0:00 Interfacing Ada95 programs to each other and to C and C++ Joe Gwinn
1998-05-10  0:00 ` Robert Dewar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox