comp.lang.ada
 help / color / mirror / Atom feed
* Importing C Structures
@ 1995-03-23  6:34 Chris O'Regan
  1995-03-23  7:55 ` Vladimir Vukicevic
  1995-03-24 15:32 ` Robert Dewar
  0 siblings, 2 replies; 20+ messages in thread
From: Chris O'Regan @ 1995-03-23  6:34 UTC (permalink / raw)



   For my Real-Time Systems project, my partner and I are writing a program
to control a train set.  We will be working on an Indy using GNAT 2.03, and
as little C code as possible.

   We need to interface the Indy's serial port.  We have some documention
which explains how to do this in standard C, but we would prefer to do this
in Ada.  We figure that we will need to import the functions and types from
the standard C library.

   Importing a function isn't a problem, but what about data types?
Rationale and the Reference Manual claim that it is possible, but without an
sample code snippet, we don't know where to begin.

   Could someone shed some light on the subject?  Or should we give in and
write our serial port routines in C?


Chris O'Regan
Computer Engineering,
Concordia University,
Montreal, Canada.

-- 



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

* Re: Importing C Structures
  1995-03-23  6:34 Importing C Structures Chris O'Regan
@ 1995-03-23  7:55 ` Vladimir Vukicevic
  1995-03-23 18:55   ` Robert S. White
  1995-03-24 17:30   ` Robert Dewar
  1995-03-24 15:32 ` Robert Dewar
  1 sibling, 2 replies; 20+ messages in thread
From: Vladimir Vukicevic @ 1995-03-23  7:55 UTC (permalink / raw)


In article <3kr4q3$jd9@newsflash.concordia.ca> ct_oreg@vega.concordia.ca (Chris O'Regan) writes:

> 
>    For my Real-Time Systems project, my partner and I are writing a program
> to control a train set.  We will be working on an Indy using GNAT 2.03, and
> as little C code as possible.
> 
>    We need to interface the Indy's serial port.  We have some documention
> which explains how to do this in standard C, but we would prefer to do this
> in Ada.  We figure that we will need to import the functions and types from
> the standard C library.
> 
>    Importing a function isn't a problem, but what about data types?
> Rationale and the Reference Manual claim that it is possible, but without an
> sample code snippet, we don't know where to begin.
> 
>    Could someone shed some light on the subject?  Or should we give in and
> write our serial port routines in C?

No. Write them in Ada. :-)

First, decide which functions you'll need. I'm assuming open (),
read(), write(), ioctl() and the like. open () returns an int, so that's
no problem. read/write would use Interfaces.C.Strings. ioctl () would
use System.Address and others. If you need to pass around pointers,
and don't care what they point to, treat them as System.Addresses.

If there is some some struct that you need to map to Ada, it should be
farily straightforward. i.e.

typedef struct {
	int foo;
	char bar[10];
	long *q;
} A_Struct;

becomes

with Interfaces.C;
package IC renames Interfaces.C;
type A_Struct is
	record
		foo : IC.int;
		bar : IC.char_array (1 .. 10);
		q : access IC.long;
	end record;

	- Vladimir



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

* Re: Importing C Structures
  1995-03-23  7:55 ` Vladimir Vukicevic
@ 1995-03-23 18:55   ` Robert S. White
  1995-03-24  8:51     ` Vladimir Vukicevic
                       ` (3 more replies)
  1995-03-24 17:30   ` Robert Dewar
  1 sibling, 4 replies; 20+ messages in thread
From: Robert S. White @ 1995-03-23 18:55 UTC (permalink / raw)


In article <VLADIMIR.95Mar22235527@speedy.intrepid.com>, 
vladimir@speedy.intrepid.com says...
>
>If there is some some struct that you need to map to Ada, it should be
>farily straightforward. i.e.
>        - Vladimir

Do you have a clean way to handle hardware registers that have one
meaning when you read them and another when you write to them with
nice seperate names for each type of usage?  I know "use at" for 
Ada 83 can overide this but it seems to be not in the spirit of 
the 83 LRM;
  13.5 "Address clauses should not be used to achieve overlays of
        objects...Any program using address clauses to achieve
        such effects is erroneous."
A work around is to have a dual meaning name for the register and
use one procedure, appropriately named, to write to it and a function,
again with a suitable name, for reading it.

This is a case where C programmers use the union structure.  I 
confess that I have not ferreted out in the Ada 95 RM or Rational 
the right (and very concise) way to do this now.

Recommendations? 

Robert S. White  
76166.1137@compuserve.com  -- speaking for myself only




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

* Re: Importing C Structures
  1995-03-23 18:55   ` Robert S. White
@ 1995-03-24  8:51     ` Vladimir Vukicevic
  1995-03-25  9:57       ` Keith Thompson
  1995-03-27 16:00       ` Norman H. Cohen
  1995-03-24 16:08     ` Robert I. Eachus
                       ` (2 subsequent siblings)
  3 siblings, 2 replies; 20+ messages in thread
From: Vladimir Vukicevic @ 1995-03-24  8:51 UTC (permalink / raw)


In article <3ksg66$h1c@newssvr.cacd.rockwell.com> rswhite@cacd.rockwell.com (Robert S. White) writes:

> Do you have a clean way to handle hardware registers that have one
> meaning when you read them and another when you write to them with
> nice seperate names for each type of usage?  I know "use at" for 
> Ada 83 can overide this but it seems to be not in the spirit of 
> the 83 LRM;
>   13.5 "Address clauses should not be used to achieve overlays of
>         objects...Any program using address clauses to achieve
>         such effects is erroneous."
> A work around is to have a dual meaning name for the register and
> use one procedure, appropriately named, to write to it and a function,
> again with a suitable name, for reading it.

There is no such clause in the Ada 95 LRM... the "Erroneous Execution"
section for using a X'Address representation clause (13.3 (13)) states:

       If an Address is specified, it is the programmer's responsibility
       to ensure that the address is valid; otherwise, program execution
       is erroneous. 

So, it is perfectly valid to use the same 'Address for two objects, as
long as the Address you specify is valid :-)

> This is a case where C programmers use the union structure.  I 
> confess that I have not ferreted out in the Ada 95 RM or Rational 
> the right (and very concise) way to do this now.
> 
> Recommendations? 

Something like this (in Ada 95):

Input_Register : Integer;
for Input_Register'Address use
	System.Storage_Elements.To_Address (16#0020);

Output_Register : Integer;
for Output_Register'Address use
	System.Storage_Elements.To_Address (16#0020);

This is perfectly valid and within the spirit of the 95 LRM.

	- Vladimir



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

* Re: Importing C Structures
  1995-03-23  6:34 Importing C Structures Chris O'Regan
  1995-03-23  7:55 ` Vladimir Vukicevic
@ 1995-03-24 15:32 ` Robert Dewar
  1 sibling, 0 replies; 20+ messages in thread
From: Robert Dewar @ 1995-03-24 15:32 UTC (permalink / raw)


First of all, the usual advice, if you have questions on GNAT, be SURE
to copy them to gnat-report@cs.nyu.edu which is read by the key people
on the GNAT development team, not all of whom read comp.lang.ada.

There is a simple correspondence between data in Ada and data in C
as follows:

   int -> integer
   short -> short_integer
   signed char -> short_short_integer
   long -> long integer
   char -> character

any simple records map directly to the corresponding C record.

In other words, pragma Convention C is the default for GNAT. This should
be enough to get you started. For argument passing, see the RM, except there
is ONE place we differ from the RM.

We do NOT follow the implementation advice to pass IN parameters that are
records by address, instead we pass them the same way that C would pass
the record (which seems to us a better choice). This may be by address
on some machines, but on some machines, depending on the size of the
record, they are passed by value. It seems closer to the ABI to follow
exactly the same scheme in Ada.




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

* Re: Importing C Structures
  1995-03-23 18:55   ` Robert S. White
  1995-03-24  8:51     ` Vladimir Vukicevic
@ 1995-03-24 16:08     ` Robert I. Eachus
  1995-03-24 20:20     ` Bob Gilbert
  1995-03-25 18:07     ` Robert Dewar
  3 siblings, 0 replies; 20+ messages in thread
From: Robert I. Eachus @ 1995-03-24 16:08 UTC (permalink / raw)


In article <3ksg66$h1c@newssvr.cacd.rockwell.com> rswhite@cacd.rockwell.com (Robert S. White) writes:

   > I know "use at" for Ada 83 can overide this but it seems to be
   > not in the spirit of the 83 LRM;

   >  13.5 "Address clauses should not be used to achieve overlays of
   >	   objects...Any program using address clauses to achieve
   >	   such effects is erroneous."

   This is a common misunderstanding.  When the Ada 83 RM says that
"misusing this freedom is erroneous," the intent was to lay the onus
for proper use on the programmer not the compiler. Since the stated
use does not violate the first sentence--the objects are overlayed by
the hardware, not the users program--the effect is not erroneous, but
it sure is implementation dependent.

   The wording in the 95 RM is much clearer about this, but the intent
has always been the same.  There are certain areas where compilers
cannot do sanity checks, and in those areas the responsibility for
correctness and testing falls on the user.

   > A work around is to have a dual meaning name for the register and
   > use one procedure, appropriately named, to write to it and a function,
   > again with a suitable name, for reading it.

   > This is a case where C programmers use the union structure.  I
   > confess that I have not ferreted out in the Ada 95 RM or Rational
   > the right (and very concise) way to do this now.

   > Recommendations?

    If the right C analog is a union with a field in the struct which
can be used to determine which choice is correct, write it in Ada as a
discriminated record.  If the necessary information is stored
separately or not at all, do the Ada equivalent with
Unchecked_Conversion between variants, and recognize that coding
errors are the responsibility of the programmer.  (Or fix the record
so you can let the compiler do the checking, even if it means fixing
the bug in the C code as well.)

--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...



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

* Re: Importing C Structures
  1995-03-23  7:55 ` Vladimir Vukicevic
  1995-03-23 18:55   ` Robert S. White
@ 1995-03-24 17:30   ` Robert Dewar
  1 sibling, 0 replies; 20+ messages in thread
From: Robert Dewar @ 1995-03-24 17:30 UTC (permalink / raw)


Vladimir writes:

type A_Struct is
        record
                foo : IC.int;
                bar : IC.char_array (1 .. 10);
                q : access IC.long;
        end record;

that's wrong, you can't use anonymous access types like this (It's always
a good idea to compile code that you put on CLA, to protect against
slipups like this, which can confuse the unwary).

If I were doing this in GNAT, I wouldn't bother with Interfaces.C, since
obviously you are not trying to write code that can be ported to other
Ada 95 compilers. Instead I would just write

type A_Struct is
  record
     foo : Integer;
     bar : String (0 .. 9);
     q   : Access_Long_Integer;
  end record;

it is particularly nice to avoid the To_Ada and To_C stuff for converting
between GNAT Character/String and C char/char*, since these are always
the same in GNAT. Interfaces.C is predicated on the assumption that Ada
and C will use different data structures for basic data. THis assumption
is wrong for GNAT.

Of course if you want to write code that will port to other Ada 95 compilers
that might make less convenient choices, then you can use Interfaces.C




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

* Re: Importing C Structures
  1995-03-23 18:55   ` Robert S. White
  1995-03-24  8:51     ` Vladimir Vukicevic
  1995-03-24 16:08     ` Robert I. Eachus
@ 1995-03-24 20:20     ` Bob Gilbert
  1995-03-25 18:07     ` Robert Dewar
  3 siblings, 0 replies; 20+ messages in thread
From: Bob Gilbert @ 1995-03-24 20:20 UTC (permalink / raw)


In article h1c@newssvr.cacd.rockwell.com, rswhite@cacd.rockwell.com (Robert S. White) writes:
->
->Do you have a clean way to handle hardware registers that have one
->meaning when you read them and another when you write to them with
->nice seperate names for each type of usage?  I know "use at" for 
->Ada 83 can overide this but it seems to be not in the spirit of 
->the 83 LRM;
->  13.5 "Address clauses should not be used to achieve overlays of
->        objects...Any program using address clauses to achieve
->        such effects is erroneous."
->A work around is to have a dual meaning name for the register and
->use one procedure, appropriately named, to write to it and a function,
->again with a suitable name, for reading it.
->
->This is a case where C programmers use the union structure.  I 
->confess that I have not ferreted out in the Ada 95 RM or Rational 
->the right (and very concise) way to do this now.
->
->Recommendations? 

Well, using Ada 83 there are a couple of ways.  You are correct about
avoiding the address clause to "overlay" two or more objects to the 
same memory location.

If the location has different meaning when read from that when written
to, I would use Unchecked_Conversion and do something like the following:

     package Whatever_Interface is

       type READ_WHATEVER is record ..... end record;
       type WRITE_WHATEVER is record .... end record;

       procedure Write(Val : in WRITE_WHATEVER);

       function Read return READ_WHATEVER;

     end Whatever_Interface;

     with System;
     with Unchecked_Conversion;
     package body Whatever_Interface is

       Whatever : WRITE_WHATEVER;
         for Whatever use at {put address here};

       procedure Write(Val : in WRITE_WHATEVER) is
       begin
         Whatever := Val;
       end Write;

       function Read return READ_WHATEVER is
         function To_Read_Type is new
           Unchecked_Conversion(WRITE_WHATEVER, READ_WHATEVER);
       begin
         return To_Read_Type(Whatever);
       end Read;

     end Whatever_Interface;

The advantage of using the packaging and procedure/function to access
the location is that it allows protection of the object. You can only
write a valid type to it as well as returning the proper type when
using the function to read the object. You can use pragma Inline if
there are concerns about the overhead in making these simple calls.
Most reasonable compilers will optimize the code generated such that
it will appear to give direct access to the memory location.

Of course if you really want to "overlay" two seperate objects to the
same location, you can probably make the assumption that access types
are implemented as addresses, and you could then do the following:

     with System;
     with Unchecked_Conversion;
     package Whatever_Interface is

       Location : constant System.ADDRESS := {put address here};

       type READ_WHATEVER is record ..... end record;
       type WRITE_WHATEVER is record .... end record;

       type READ_WHATEVER_PTR is access READ_WHATEVER;
       type WRITE_WHATEVER_PTR is access WRITE_WHATEVER;

       function To_Ptr is new 
         Unchecked_Conversion(System.ADDRESS, READ_WHATEVER_PTR);

       function To_Ptr is new 
         Unchecked_Conversion(System.ADDRESS, WRITE_WHATEVER_PTR);

       Read_Val  : constant READ_WHATEVER_PTR  := To_Ptr(Location);
       Write_Val : constant WRITE_WHATEVER_PTR := To_Ptr(Location);

     end Whatever_Interface;

Of course you have to remember to use the ".all" notation to make sure
you are referencing the value "pointed" to by the access value(s).  This 
is probably considered bastardized Ada code.  It is dangerous since you
can write a read type value (Read_Val := xxx) and the compiler will offer
no protection. It also relies on the knowlege that access types are 
implemented as an address (not required by the LRM, but usually true).
Note that at least I made the access (pointer) values constants so that
they are protected from accidental modification (also stating that something
you intend to be constant with the key word "constant" frequently allows the
compiler to make advantageous assumptions during optimization).

Now with Ada 83 the first example may have a problem using the address
clause.  Many compilers will perform a write to the location during
elaboration (I guess to insure that any initialization that might have
been specified is performed).  This is the reason I used the 
WRITE_WHATEVER type to define the object.  If this should be a problem,
you can use the access type to map the object in the same style as done
in the second example.  

As for Ada 95, I'll quote Tucker Taft from a previous post:
  --------------------------------------------------------------
   In Ada 95, you can specify "pragma Import(Ada, <object-name>);"
   which indicates that *no* default initialization is to be performed
   by the compiler-generated code.  This is generally desirable when
   using an address clause to associate a name with a machine register
   of some sort.

   Also, in Ada 95 there are language-defined functions for converting
   integers to addresses.  Finally, the preferred syntax for
   specifying the address of an object uses "for ...'Address use ...",
   such as:

      for Console_Status_Register'Address use 
        System.Storage_Elements.To_Address(16#FFC0#);

   The "for ... use at ..." syntax is still retained for upward 
   compatibility reasons.
  --------------------------------------------------------------

-Bob





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

* Re: Importing C Structures
  1995-03-24  8:51     ` Vladimir Vukicevic
@ 1995-03-25  9:57       ` Keith Thompson
  1995-03-26 13:16         ` Larry Kilgallen, LJK Software
  1995-03-27 16:00       ` Norman H. Cohen
  1 sibling, 1 reply; 20+ messages in thread
From: Keith Thompson @ 1995-03-25  9:57 UTC (permalink / raw)


In <VLADIMIR.95Mar24005132@speedy.intrepid.com> vladimir@speedy.intrepid.com (Vladimir Vukicevic) writes:
> There is no such clause in the Ada 95 LRM... the "Erroneous Execution"
> section for using a X'Address representation clause (13.3 (13)) states:
> 
>        If an Address is specified, it is the programmer's responsibility
>        to ensure that the address is valid; otherwise, program execution
>        is erroneous. 
> 
> So, it is perfectly valid to use the same 'Address for two objects, as
> long as the Address you specify is valid :-)

Here's an example of an erroneous use of address clauses in Ada 83:

    X : Integer;
    ...
    Y : Integer;
    for Y use at X'Address;

The reason this is erroneous is that the compiler may not be aware that
X and Y are really the same object (X may be declared in a different
compilation unit, or the overlaid object might be something more
complex than a simple object, say a dynamically indexed array element).
The compiler is free to keep the value of X in a register, optimize out
dead assignments, etc., so the apparent values of X and Y won't track
each other as the user might naively expect.

The AARM, if I'm reading it correctly, still gives implementations
considerable freedom to treat such constructs as erroneous.
Paragraph 13.3(13) says

        If an Address is specified, it is the programmer's
        responsibility to ensure that the address is valid;
        otherwise, program execution is erroneous.

What does "valid" mean in this context?  See paragraph 12.b in the
same subsection:

        The validity of a given address depends on the run-time
        model; thus, in order to use Address clauses correctly,
        one needs intimate knowledge of the run-time model.

Caveat hacker.

A minor digression:

Initialization of objects with address clauses has caused a lot of
problems in Ada 83; the language doesn't give permission not to initialize
such objects, but if you're trying to map an access or System.Address
object to a hardware register you probably don't want it initialized
to null.  Paragraph 12.c of the AARM says:

        If the Address of an object is specified, any explicit
        or implicit initialization takes place as usual,
        unless a pragma Import is also specified for the
        object (in which case any necessary initialization
        is presumably done in the foreign language).

(The language specified in the pragma Import can be Ada.)

-- 
Keith Thompson (The_Other_Keith)  kst@thomsoft.com (kst@alsys.com still works)
TeleSoft^H^H^H^H^H^H^H^H Alsys^H^H^H^H^H Thomson Software Products
10251 Vista Sorrento Parkway, Suite 300, San Diego, CA, USA, 92121-2718
That's Keith Thompson *with* a 'p', Thomson Software Products *without* a 'p'.



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

* Re: Importing C Structures
  1995-03-23 18:55   ` Robert S. White
                       ` (2 preceding siblings ...)
  1995-03-24 20:20     ` Bob Gilbert
@ 1995-03-25 18:07     ` Robert Dewar
  3 siblings, 0 replies; 20+ messages in thread
From: Robert Dewar @ 1995-03-25 18:07 UTC (permalink / raw)


Another way to deal with giving different names for reading and writing
the same  memory location would simply be to rename it with appropriate
names, and then by convention use the appropriate name. This wouldn't
enforce the right name use, but would permit it, and that may be perfectly
good enough. One doesn't always need enforce mechanisms for ensuring that
one's own code is not incompetently written :-)




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

* Re: Importing C Structures
  1995-03-25  9:57       ` Keith Thompson
@ 1995-03-26 13:16         ` Larry Kilgallen, LJK Software
  1995-03-27  0:00           ` Kevin F. Quinn
                             ` (2 more replies)
  0 siblings, 3 replies; 20+ messages in thread
From: Larry Kilgallen, LJK Software @ 1995-03-26 13:16 UTC (permalink / raw)


In article <D5zqB9.5F8@thomsoft.com>, kst@thomsoft.com (Keith Thompson) writes:

> Here's an example of an erroneous use of address clauses in Ada 83:
> 
>     X : Integer;
>     ...
>     Y : Integer;
>     for Y use at X'Address;
> 
> The reason this is erroneous is that the compiler may not be aware that
> X and Y are really the same object (X may be declared in a different
> compilation unit, or the overlaid object might be something more
> complex than a simple object, say a dynamically indexed array element).
> The compiler is free to keep the value of X in a register, optimize out
> dead assignments, etc., so the apparent values of X and Y won't track

For an address representation clause, which might be used to access hardware,
optimizing out dead assignments seems quite inappropriate.  Is there no
Ada83 method of avoiding such an optimization for such objects?



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

* Re: Importing C Structures
  1995-03-26 13:16         ` Larry Kilgallen, LJK Software
@ 1995-03-27  0:00           ` Kevin F. Quinn
  1995-04-07  0:00             ` Larry Kilgallen
  1995-03-27 15:35           ` Theodore Dennison
  1995-03-27 23:39           ` Importing C Structures Keith Thompson
  2 siblings, 1 reply; 20+ messages in thread
From: Kevin F. Quinn @ 1995-03-27  0:00 UTC (permalink / raw)


In article <1995Mar26.081652.9489@eisner>,
          kilgallen@eisner.decus.org (Larry Kilgallen, LJK Software) wrote:

> In article <D5zqB9.5F8@thomsoft.com>, kst@thomsoft.com (Keith Thompson) writes:
> 
> > Here's an example of an erroneous use of address clauses in Ada 83:
> > 
> >     X : Integer;
> >     ...
> >     Y : Integer;
> >     for Y use at X'Address;
> > 
> > The reason this is erroneous is that the compiler may not be aware that
> > X and Y are really the same object (X may be declared in a different
> > compilation unit, or the overlaid object might be something more
> > complex than a simple object, say a dynamically indexed array element).
> > The compiler is free to keep the value of X in a register, optimize out
> > dead assignments, etc., so the apparent values of X and Y won't track

You're correct (of course :) ) but I would expect the situation
with more complex objects, especially ones involving dynamically
chosen elements to be very rare indeed.  Especially justifiable
situations...

> 
> For an address representation clause, which might be used to access hardware,
> optimizing out dead assignments seems quite inappropriate.  Is there no
> Ada83 method of avoiding such an optimization for such objects?

The problem occurs with 'X', which the compiler is free to handle
purely in a register for a while if that is appropriate; it doesn't
know that an interrupt handler which uses Y can come in expecting
Y to be the same as X at all times, for example.  Possibly a bit of
a contrived situation, but if it can be done, it probably will be
done by someone somewhere :)

Dead assignments for Y should never be optimised away, for the
reasons you mention, Larry.  Not that I'd trust a compiler in this;
I'd always take a glance at the assembly listing to be sure...

Most compilers I've used have a "pragma Volatile" or similar, which
marks a variable so that the optimiser leaves it in memory.  If your
compiler doesn't have a suitable pragma (and it doesn't have to), you
can try:

   private_XY : Integer;
   
   X : Integer;
   for X use at private_Z'address;
   Y : Integer;
   for Y use at private_Z'address;

Then you can use X and Y with impunity - if the compiler is worth
anything then both X and Y will always be accessed over the bus.
Leave it to coding standards to ensure that private_XY is never
used.  This can be done in all situations, including ones where
data is declared in a new block (hence is declared dynamically,
probably on a stack or heap).

I'm not sure if you can put private_XY in a package body, vis:

  package MyData is
    X : Integer;
    Y : Integer;
  end MyData;
  
  package body MyData is
    private_XY : Integer;
    for X use at private_XY'address;
    for Y use at private_XY'address;
  end Mydata;

It might work though (don't have a compiler here to check...),
in which case you will have enforced the non-use of private_XY
by packaging.

If you're relying on this kind of thing, it is always best to
check your object code just to be sure, anyway.  I may be
stating the obvious, but then again...

Especially since you'll need to give VERY good reasons why
you're doing it in the first place :)

-- 
Kevin F. Quinn           * "No-one ever made any money out of good
kevq@banana.demon.co.uk  *  looks and charm."
kevq@cix.compulink.co.uk * "You obviously haven't met Lady Hamilton..."
Compu$erve: 100025,1525  *                               Blackadder III
... I'll have what the guy on the floor is having...




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

* Re: Importing C Structures
  1995-03-26 13:16         ` Larry Kilgallen, LJK Software
  1995-03-27  0:00           ` Kevin F. Quinn
@ 1995-03-27 15:35           ` Theodore Dennison
  1995-03-28  0:00             ` Robert Dewar
  1995-03-28 11:44             ` Keith Thompson
  1995-03-27 23:39           ` Importing C Structures Keith Thompson
  2 siblings, 2 replies; 20+ messages in thread
From: Theodore Dennison @ 1995-03-27 15:35 UTC (permalink / raw)


Keith Thompson <kilgallen@eisner.decus.org> wrote:
> In article <D5zqB9.5F8@thomsoft.com>, kst@thomsoft.com (Keith Thompson) writes:
> 
> For an address representation clause, which might be used to access hardware,
> optimizing out dead assignments seems quite inappropriate.  Is there no
> Ada83 method of avoiding such an optimization for such objects?

There is no PORTABLE way. Most compiler vendors however will tell you what you
can do to avoid this. The DEC Ada compiler, if memory serves, treated any 
variable associated with an address clause as "volatile" for the scope of the
address clause. "Volatile" addresses are not optimized into registers. Again,
this is DEC Ada only. Check your vendor docs.

T.E.D.




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

* Re: Importing C Structures
  1995-03-24  8:51     ` Vladimir Vukicevic
  1995-03-25  9:57       ` Keith Thompson
@ 1995-03-27 16:00       ` Norman H. Cohen
  1 sibling, 0 replies; 20+ messages in thread
From: Norman H. Cohen @ 1995-03-27 16:00 UTC (permalink / raw)


In article <VLADIMIR.95Mar24005132@speedy.intrepid.com>,
vladimir@speedy.intrepid.com (Vladimir Vukicevic) writes: 

|> In article <3ksg66$h1c@newssvr.cacd.rockwell.com> rswhite@cacd.rockwell.com (Robert S. White) writes: 
|>
|> > Do you have a clean way to handle hardware registers that have one
|> > meaning when you read them and another when you write to them with
|> > nice seperate names for each type of usage?
...
|> > Recommendations?
|>
|> Something like this (in Ada 95): 
|>
|> Input_Register : Integer;
|> for Input_Register'Address use
|>      System.Storage_Elements.To_Address (16#0020);
|>
|> Output_Register : Integer;
|> for Output_Register'Address use
|>      System.Storage_Elements.To_Address (16#0020);
|>
|> This is perfectly valid and within the spirit of the 95 LRM.

Yes, it is.  Personally, I think memory-mapped I/O is a pernicious
abstraction.  Just because the hardware lies and claims that we are
reading from or writing to a storage location when we are reading from
or writing to a device, I see no need to perpetuate this lie in the
source program and make it appear as though we are reading from or
writing to a variable.  Therefore, I would prefer a procedural interface: 

  with System;
  package Low_Level_IO is  -- Loosely inspired by RM83 14.6
     type Device_Address is new System.Address;
     type Word is mod 2**32; -- or whatever
     procedure Send_Control (Device: in Device_Address; Data: in Word);
     procedure Receive_Control
        (Device: in Device_Address; Data: out Word);
  end Low_Level_IO;

  with System.Address_To_Access_Conversions;
  package body Low_Level_IO is

     use System;

     package Word_Pointers is new Address_To_Access_Conversions (Word);

     procedure Send_Control (Device: in Device_Address; Data: in Word) is
     begin
        Word_Pointers.To_Pointer(Address(Device)).all := Data;
     end Send_Control;

     procedure Receive_Control
        (Device: in Device_Address; Data: out Word) is
     begin
        Data := Word_Pointers.To_Pointer(Address(Device)).all;
     end Receive_Control;

  end Low_Level_IO;

Code procedures would provide even less of a suggestion that some
variable is being updated or referenced.

--
Norman H. Cohen    ncohen@watson.ibm.com



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

* Re: Importing C Structures
  1995-03-26 13:16         ` Larry Kilgallen, LJK Software
  1995-03-27  0:00           ` Kevin F. Quinn
  1995-03-27 15:35           ` Theodore Dennison
@ 1995-03-27 23:39           ` Keith Thompson
  2 siblings, 0 replies; 20+ messages in thread
From: Keith Thompson @ 1995-03-27 23:39 UTC (permalink / raw)


In <1995Mar26.081652.9489@eisner> kilgallen@eisner.decus.org (Larry Kilgallen, LJK Software) writes:
> In article <D5zqB9.5F8@thomsoft.com>, kst@thomsoft.com (Keith Thompson) writes:
> > Here's an example of an erroneous use of address clauses in Ada 83:
> > 
> >     X : Integer;
> >     ...
> >     Y : Integer;
> >     for Y use at X'Address;

[...]

> For an address representation clause, which might be used to access hardware,
> optimizing out dead assignments seems quite inappropriate.  Is there no
> Ada83 method of avoiding such an optimization for such objects?

I certainly agree that optimizing out dead assignments for an object
to which an address clause applies is inappropriate.  I suspect most or
all Ada 83 compilers treat such objects specially (but consult your
compiler documentation to be sure).  In the example, accesses to Y
are probably safe from such optimizations.

The problem is that access to X may not be safe.  If you write a value
to X (which *doesn't* have an address clause) and then try to read it
through Y, you may not get the results you expect, since the generated
code might not bother to store the value at X's address.  This is an
example of a general problem with aliasing; I think you can run into
the same kind of problems with subprogram parameters passed by reference.

It is possible for a compiler to do the analysis needed to mark any
*potentially* aliased objects as volatile, avoiding this problem, but
I don't know how many actual compilers do so.  Any variable visible to
other compilation units can be aliased in this way.  (There presumably
won't be very many such objects in well-designed code.)

To summarize, if you alias two declared objects by using an address
clause, it's likely that they'll behave as you'd expect, but it's usually
far better to use other methods.  If you want to alias an object with
the same type, use a renames declaration; if you need a different type,
use Unchecked_Conversion (which explicitly accesses the aliased object).

-- 
Keith Thompson (The_Other_Keith)  kst@thomsoft.com (kst@alsys.com still works)
TeleSoft^H^H^H^H^H^H^H^H Alsys^H^H^H^H^H Thomson Software Products
10251 Vista Sorrento Parkway, Suite 300, San Diego, CA, USA, 92121-2718
That's Keith Thompson *with* a 'p', Thomson Software Products *without* a 'p'.



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

* Re: Importing C Structures
  1995-03-27 15:35           ` Theodore Dennison
@ 1995-03-28  0:00             ` Robert Dewar
  1995-03-28 11:44             ` Keith Thompson
  1 sibling, 0 replies; 20+ messages in thread
From: Robert Dewar @ 1995-03-28  0:00 UTC (permalink / raw)


T.E.D says "volatile is in Dec Ada only".

And in Ada 95, where it is one of the predefined pragmas (and is 
currently implemented in GNAT).

One thing to be concerned with is that if you map to hardware memory
addressed locations, you are making non-portable, target dependent
assumptions about the exact sequence of instructions that will be
generated. For example, if you map to a byte, normally the code
generator could use a load word/extract byte sequence or a load
byte instruction. Normally the choice would make no difference,
but it could make a BIG DIFFERENCE in the memory mapped case.

In a way, I would prefer to see the use of a machine instrinsic
instruction (coming soon in GNAT!) for this purpose, to make it
absolutely CLEAR what is going on without hidden assumptions.





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

* Re: Importing C Structures
  1995-03-27 15:35           ` Theodore Dennison
  1995-03-28  0:00             ` Robert Dewar
@ 1995-03-28 11:44             ` Keith Thompson
  1995-03-29  0:00               ` misattrubation (was: Re: Importing C Structures) Theodore Dennison
  1 sibling, 1 reply; 20+ messages in thread
From: Keith Thompson @ 1995-03-28 11:44 UTC (permalink / raw)


In <3l6m0b$pj9@theopolis.orl.mmc.com> Theodore Dennison <dennison@escmail.orl.mmc.com> writes:
> Keith Thompson <kilgallen@eisner.decus.org> wrote:
  ^^^^^^^^^^^^^^
> > In article <D5zqB9.5F8@thomsoft.com>, kst@thomsoft.com (Keith Thompson) writes:
> > 
> > For an address representation clause, which might be used to access hardware,
> > optimizing out dead assignments seems quite inappropriate.  Is there no
> > Ada83 method of avoiding such an optimization for such objects?

Just to set things straight, "kilgallen@eisner.decus.org" is Larry
Kilgallen of LJK Software; he wrote the quoted paragraph in response
to something I posted.  Though my name appears in Theodore Dennison's
article, he didn't quote anything that I wrote.

No biggie; I'm sure it was just a simple mistake.

-- 
Keith Thompson (The_Other_Keith)  kst@thomsoft.com (kst@alsys.com still works)
TeleSoft^H^H^H^H^H^H^H^H Alsys^H^H^H^H^H Thomson Software Products
10251 Vista Sorrento Parkway, Suite 300, San Diego, CA, USA, 92121-2718
That's Keith Thompson *with* a 'p', Thomson Software Products *without* a 'p'.



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

* misattrubation (was: Re: Importing C Structures)
  1995-03-28 11:44             ` Keith Thompson
@ 1995-03-29  0:00               ` Theodore Dennison
  1995-03-31  0:00                 ` Theodore Dennison
  0 siblings, 1 reply; 20+ messages in thread
From: Theodore Dennison @ 1995-03-29  0:00 UTC (permalink / raw)
  To: kst

Keith Thompson <kst@thomsoft.com> wrote:
> Just to set things straight, "kilgallen@eisner.decus.org" is Larry
> Kilgallen of LJK Software; he wrote the quoted paragraph in response
> to something I posted.  Though my name appears in Theodore Dennison's
> article, he didn't quote anything that I wrote.
> 
> No biggie; I'm sure it was just a simple mistake.
> 

Sorry about that. 

Lame excuse:
    I'm using the new Beta version of Netscape to read my news. In 
this version they removed the feature that automaticly puts the 
author's name at the top of a follow-up post, so now I have to do it
manually. As a human, I'm apt to screw this up once in a while (as
T.E.D., I'm apt to screw this up quite often). One of the things I'm
best at is making mistakes, which is why I like Ada so much.

It also now automaticly e-mails a copy of the posting to the previous 
author, unless you tell it not to. So if you are suddenly seeing a lot of 
misattrubations and email identical to postings (particularly from me)
now you know why.

Thanks for letting me know it happened. I'll try to be a bit more
careful.

T.E.D. (structured programming bigot)





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

* Re: misattrubation (was: Re: Importing C Structures)
  1995-03-29  0:00               ` misattrubation (was: Re: Importing C Structures) Theodore Dennison
@ 1995-03-31  0:00                 ` Theodore Dennison
  0 siblings, 0 replies; 20+ messages in thread
From: Theodore Dennison @ 1995-03-31  0:00 UTC (permalink / raw)


Theodore Dennison <dennison@escmail.orl.mmc.com> wrote:
>Lame excuse:
>    I'm using the new Beta version of Netscape to read my news. In 
>this version they removed the feature that automaticly puts the 
>author's name at the top of a follow-up post, so now I have to do it
>manually. As a human, I'm apt to screw this up once in a while (as


Sorry to reply to my own post, but for those of you using Netscape, 
there is now a new version that fixes the aforementioned problem.
It is version 1.1b2, and is available through the netscape home page.

So hopefully, this was the one and only instance of me making this 
mistake.

Note that it still e-mails each post unless you stop it.

T.E.D.





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

* Re: Importing C Structures
  1995-03-27  0:00           ` Kevin F. Quinn
@ 1995-04-07  0:00             ` Larry Kilgallen
  0 siblings, 0 replies; 20+ messages in thread
From: Larry Kilgallen @ 1995-04-07  0:00 UTC (permalink / raw)


In article <19950327.180750.74@banana.demon.co.uk>, kevq@banana.demon.co.uk (Kevin F. Quinn) writes:
> In article <1995Mar26.081652.9489@eisner>,
>           kilgallen@eisner.decus.org (Larry Kilgallen, LJK Software) wrote:
> 

> > For an address representation clause, which might be used to access hardware,
> > optimizing out dead assignments seems quite inappropriate.  Is there no
> > Ada83 method of avoiding such an optimization for such objects?

> Most compilers I've used have a "pragma Volatile" or similar, which
> marks a variable so that the optimiser leaves it in memory.  If your

Oh, the compiler I use has lots of that stuff, but it is printed in blue
ink (non-standard) and this seems such a basic concept (for a language
that provides Address clauses at all) that I was hoping for a standard
method.

Since one is looking at machine addresses, the code is by definition
non-portable, but recent experience in another language has made me
hyper-sensitive to vendor-specific enhancements.  If someday there were
a second compiler vendor for the platform, standard syntax might be
useful.

Larry Kilgallen




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

end of thread, other threads:[~1995-04-07  0:00 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1995-03-23  6:34 Importing C Structures Chris O'Regan
1995-03-23  7:55 ` Vladimir Vukicevic
1995-03-23 18:55   ` Robert S. White
1995-03-24  8:51     ` Vladimir Vukicevic
1995-03-25  9:57       ` Keith Thompson
1995-03-26 13:16         ` Larry Kilgallen, LJK Software
1995-03-27  0:00           ` Kevin F. Quinn
1995-04-07  0:00             ` Larry Kilgallen
1995-03-27 15:35           ` Theodore Dennison
1995-03-28  0:00             ` Robert Dewar
1995-03-28 11:44             ` Keith Thompson
1995-03-29  0:00               ` misattrubation (was: Re: Importing C Structures) Theodore Dennison
1995-03-31  0:00                 ` Theodore Dennison
1995-03-27 23:39           ` Importing C Structures Keith Thompson
1995-03-27 16:00       ` Norman H. Cohen
1995-03-24 16:08     ` Robert I. Eachus
1995-03-24 20:20     ` Bob Gilbert
1995-03-25 18:07     ` Robert Dewar
1995-03-24 17:30   ` Robert Dewar
1995-03-24 15:32 ` Robert Dewar

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