Version 1.4 of ais/ai-00181.txt

Unformatted version of ais/ai-00181.txt version 1.4
Other versions for file ais/ai-00181.txt

!standard 13.13.01 (04)          99-08-31 AI95-00181/03
!standard 13.13.01 (09)
!class binding interpretation 97-03-19
!status Corrigendum 2000 99-05-27
!status WG9 Approved 97-11-14
!status ARG Approved (letter ballot: 9-1-1) 97-10-27
!status ARG Approved (subject to letter ballot) 8-1-1 97-04-11
!status work item 97-03-19
!status received 97-03-19
!priority High
!difficulty Easy
!qualifier Clarification
!subject Components of Stream_Element_Array should be Aliased
!summary
The components of Streams.Stream_Element_Array are aliased:
type Stream_Element_Array is array(Stream_Element_Offset range <>) of aliased Stream_Element; ^^^^^^^
Implementation Permission:
If Stream_Element'Size is not a multiple of System.Storage_Unit, then the components of Stream_Element_Array need not be aliased.
!question
13.13.1(4) does not define the components of Streams.Stream_Element_Array to be aliased. However, this makes various uses of this type inconvenient. What is the intent?
!recommendation
On machines where it is feasible, the components should be aliased.
!wording
(See Summary.)
!discussion
On machines where it is feasible, one should be allowed to form access values pointing to any component within a Stream_Element_Array. However, this package was intentionally designed to support machines where the addressable unit is different from the unit of storage used by the "network". Therefore, the requirement to be aliased is relaxed on such machines. Programmers wishing to write code that is portable to such machines should not take advantage of the aliased components.
!corrigendum 13.13.01(4)
Replace:
type Stream_Element_Array is array(Stream_Element_Offset range <>) of Stream_Element;
by:
type Stream_Element_Array is array(Stream_Element_Offset range <>) of aliased Stream_Element;
!corrigendum 13.13.01(9)
Insert after the paragraph:
The Write operation appends Item to the specified stream.
the new paragraph:
Implementation Permissions
If Stream_Element'Size is not a multiple of System.Storage_Unit, then the components of Stream_Element_Array need not be aliased.
!ACATS test
A C-Test should be created to check that the components are aliased. There should be applicability criteria allowing the test to be rejected (similarly to the representation clause tests), and marked Not Applicable for an implementation taking advantage of the implementation permission.
!appendix

!section 13.13.1(00)
!subject components of Stream_Element_Array should be ALIASED
!reference RM95-13.13.1
!from Ted Baker 97-3-7
!reference 97-15725.a Ted Baker  97-3-7>>
!discussion

The word "aliased" should be added to the declaration of type
Stream_Element array.

The intended use of this type is for buffers.  When one attempts
to use this type for that purpose, one finds it necessary to pass
pointers to buffers (and to subfields within buffers) to device
drivers or the operating system.  At present, this is not
possible, and so one either must waste time copying entire buffers
into aliased arrays (terribly inefficient) or use some
non-portable hack.

I suspect the omission of "aliased" was an oversight, and hope that
it can be corrected.

****************************************************************

!section 13.13.1(00)
!subject components of Stream_Element_Array should be ALIASED
!reference RM95-13.13.1
!reference as 97-15725.a Ted Baker  97-3-7
!from Ted Baker 97-3-10
!reference 97-15726.a Ted Baker  97-3-9>>
!discussion

Thanks to Art for pointing our a typo in my posting.
"Stream_Element array" should be "Stream_Element_Array".

--Ted Baker

****************************************************************

!section 13.13.1(0)
!subject components of Stream_Element_Array should be ALIASED
!reference RM95-13.13.1
!reference 97-15725.a Ted Baker 97-3-7
!from Tucker Taft 97-3-20
!reference 1997-15731.a Tucker Taft 1997-3-20>>
!discussion

> The word "aliased" should be added to the declaration of type
> Stream_Element array.

There is no requirement that a Stream_Element be as big as
a Storage_Element.  In fact, it was anticipated that
on word-addressible machines with word sizes such as 24 bits or
36 bits, Stream_Elements would still be 8 or 9 bits, representing
the unit of I/O, rather than the unit of addressibility.

> The intended use of this type is for buffers.  When one attempts
> to use this type for that purpose, one finds it necessary to pass
> pointers to buffers (and to subfields within buffers) to device
> drivers or the operating system.  At present, this is not
> possible, and so one either must waste time copying entire buffers
> into aliased arrays (terribly inefficient) or use some
> non-portable hack.

Either you can pass a slice, or pass 'Address (which doesn't seem
like a non-portable "hack" at this level).

> I suspect the omission of "aliased" was an oversight, and hope that
> it can be corrected.

No, it was not an oversight.  We should have explained why.

-Tuck

****************************************************************

!section 13.13.1(0)
!subject components of Stream_Element_Array should be ALIASED
!reference RM95-13.13.1
!reference 97-15725.a Ted Baker 97-3-7
!from Ted Baker 97-3-21
!reference 97-15732.a Ted Baker  97-3-21>>
!discussion

Tucker Taft said:

| There is no requirement that a Stream_Element be as big as
| a Storage_Element.  In fact, it was anticipated that
| on word-addressible machines with word sizes such as 24 bits or
| 36 bits, Stream_Elements would still be 8 or 9 bits, representing
| the unit of I/O, rather than the unit of addressibility.

Such machines are rather rare.  Could we not at least give a
recommendation (or at least permission) for an implementation to
add "aliased" to this array type declaration if Stream_Element's
are addressable units?

This comes from our work with POSIX Ada bindings.
We are always interfacing to C libraries for system services.
In C, stream elements are referenced as "char *" or "u_char *".
In such environments, there is no question about whether a
stream element is addressable.

| Either you can pass a slice

Taking 'unchecked_access of an Ada slice and passing it as a C
"char *" will not work, since the slice includes the index range
information which the C side is not expecting.

| or pass 'Address (which doesn't seem
| like a non-portable "hack" at this level).

Yes, I am currently using 'Address and unchecked-converting it to
an Ada type that corresponds to a C "char *" -- just like I did in
Ada'83.  This makes the whole Ada'95 business of Interfaces.C,
'unchecked_access, etc. look pretty futile.

--Ted Baker

****************************************************************

!section 13.13.1(0)
!subject components of Stream_Element_Array should be ALIASED
!reference RM95-13.13.1
!reference 97-15725.a Ted Baker 97-3-7
!reference 97-15731.a Tucker Taft 97-3-20
!reference 97-15732.a Ted Baker 97-3-21
!from Tucker Taft 97-3-21
!reference 1997-15734.a Tucker Taft 1997-3-21>>
!discussion

> Tucker Taft said:
>
> | There is no requirement that a Stream_Element be as big as
> | a Storage_Element.  In fact, it was anticipated that
> | on word-addressible machines with word sizes such as 24 bits or
> | 36 bits, Stream_Elements would still be 8 or 9 bits, representing
> | the unit of I/O, rather than the unit of addressibility.
>
> Such machines are rather rare.  Could we not at least give a
> recommendation (or at least permission) for an implementation to
> add "aliased" to this array type declaration if Stream_Element's
> are addressable units?

This seems like the wrong way to "address" this problem ;-).

How about declaring your own array type Aliased_Stream_Element_Array,
and converting to that when you need to take '[Unchecked_]Access.
Surprisingly, and perhaps mistakenly, conversions are permitted
from an array with unaliased components to one with aliased
components.  Now whether that will result in a copy depends
on the compiler, but I suspect it won't in any compiler for
which stream elements are individually addressible (though heaven
help the high-powered optimizer).  That should be as portable
as relying on the vendor to put "aliased" on Stream_Element itself.

> This comes from our work with POSIX Ada bindings.
> We are always interfacing to C libraries for system services.
> In C, stream elements are referenced as "char *" or "u_char *".
> In such environments, there is no question about whether a
> stream element is addressable.

Actually, it was the POSIX idea of "IO_element" or equivalent
that suggested that we define Stream_Element rather than reuse
Storage_Element.

> --Ted Baker

-Tuck

****************************************************************

!section 13.13.1(0)
!subject components of Stream_Element_Array should be ALIASED
!reference RM95-13.13.1
!reference 97-15725.a Ted Baker 97-3-7
!reference 97-15731.a Tucker Taft 97-3-20
!reference 97-15732.a Ted Baker 97-3-21
!from Ted Baker 97-3-21
!reference 97-15735.a Ted Baker  97-3-21>>
!discussion

| How about declaring your own array type Aliased_Stream_Element_Array,
| and converting to that when you need to take '[Unchecked_]Access.
| Surprisingly, and perhaps mistakenly, conversions are permitted
| from an array with unaliased components to one with aliased
| components.  Now whether that will result in a copy depends
| on the compiler, but I suspect it won't in any compiler for
| which stream elements are individually addressible (though heaven
| help the high-powered optimizer).  That should be as portable
| as relying on the vendor to put "aliased" on Stream_Element itself.

Interesting idea.  I will try it with GNAT, and see whether a copy
is generated.

| Actually, it was the POSIX idea of "IO_element" or equivalent
| that suggested that we define Stream_Element rather than reuse
| Storage_Element.

Very strange.  That must have been a very early draft you looked
at.  There is no "IO_Element" in the POSIX.5 standard.  The IO
operations are defined as follows:

   subtype IO_Buffer is POSIX.POSIX_String;
   procedure Read
      (File:           in  File_Descriptor;
       Buffer:         out IO_Buffer;
       Last:           out POSIX.IO_Count;
       Masked_Signals: in  POSIX.Signal_Masking:= POSIX.RTS_Signals);
   procedure Write                         -- obsolescent
      (File:           in  File_Descriptor;
       Buffer:         in  IO_Buffer;
       Last:           out POSIX.IO_Count;
       Masked_Signals: in  POSIX.Signal_Masking:= POSIX.RTS_Signals);

In POSIX.5b, these are marked as obsolescent.  The new interfaces are:

   procedure Read
      (File:           in  File_Descriptor;
       Buffer:         out Ada_Streams.Stream_Element_Array;
       Last:           out Ada_Streams.Stream_Element_Offset;
       Masked_Signals: in  POSIX.Signal_Masking:= POSIX.RTS_Signals);
   procedure Write
      (File:           in  File_Descriptor;
       Buffer:         in  Ada_Streams.Stream_Element_Array;
       Last:           out Ada_Streams.Stream_Element_Offset;
       Masked_Signals: in  POSIX.Signal_Masking:= POSIX.RTS_Signals);

The message queue extensions use the same style:

   procedure Send
      (MQ:             in Message_Queue_Descriptor;
       Message:        in Ada_Streams.Stream_Element_Array;
       Priority:       in Message_Priority;
       Masked_Signals: in POSIX.Signal_Masking:= POSIX.RTS_Signals);

   procedure Receive
      (MQ:             in  Message_Queue_Descriptor;
       Message:        out Ada_Streams.Stream_Element_Array;
       Last:           out Ada_Streams.Stream_Element_Offset;
       Priority:       out Message_Priority;
       Masked_Signals: in  POSIX.Signal_Masking:= POSIX.RTS_Signals);

IEEE Std 1003.5b-1996 also specifies some other things:

  Instantiation of Unchecked_Conversion shall be supported for
  conversions, in both directions, between the type
  Ada_Streams.Stream_Element_Array and all other types.

  The function To_POSIX_String taking arguments of type
  Stream_Element_Array shall convert an
  Ada_Streams.Stream_Element_Array value to a POSIX_String value.
  The function To_Stream_Element_Array shall convert a POSIX_String
  value to a Ada_Streams.Stream_Element_Array value.  These
  operations shall obey the semantics of instantiations of
  Unchecked_Conversion, as defined in [ARM 13.9 J.1].

I suspect now that the first quoted paragraph above was probably a
mistake, and maybe the second also.  Users of the POSIX Ada
binding will routinely need to perform bitwise conversions to and
from segments of Stream_Element_Array, and will need some portable
POSIX way of doing this that they can rely will not involve making
extra copies.

--Ted Baker

(wearing hat of JTC1 Project Editor for POSIX Ada bindings on top of ARG hat)

****************************************************************

!section 13.13.1(0)
!subject components of Stream_Element_Array should be ALIASED
!reference RM95-13.13.1
!reference 97-15725.a Ted Baker 97-3-7
!reference 97-15731.a Tucker Taft 97-3-20
!from Randy Brukardt 97-3-21
!reference 97-15736.a Randy Brukardt  97-3-21>>
!discussion

>> The word "aliased" should be added to the declaration of type
>> Stream_Element array.
>
>There is no requirement that a Stream_Element be as big as
>a Storage_Element.  In fact, it was anticipated that
>on word-addressible machines with word sizes such as 24 bits or
>36 bits, Stream_Elements would still be 8 or 9 bits, representing
>the unit of I/O, rather than the unit of addressibility.

Indeed, in the U2200 compiler, we did exactly that.  Storage_Element'Size = 36;
Stream_Element'Size =9.  That was the only way to match the operating system
(a Unix variant) behavior.

****************************************************************

!section 13.13.1(0)
!subject components of Stream_Element_Array should be ALIASED
!reference RM95-13.13.1
!reference 97-15725.a Ted Baker 97-3-7
!reference 97-15731.a Tucker Taft 97-3-20
!reference 97-15732.a Ted Baker 97-3-21
!reference 1997-15734.a Tucker Taft 1997-3-21
!from Bob Duff
!reference 97-15738.a Robert A Duff 97-3-22>>
!discussion

> Actually, it was the POSIX idea of "IO_element" or equivalent
> that suggested that we define Stream_Element rather than reuse
> Storage_Element.

As I recall, we originally used Storage_Element, but we changed it
because we wanted to make Streams declared-Pure.  But we did not make
System declared-Pure, because some compiler vendor(s) wanted to use an
access type as the full type for type Address.  Given that, it would be
illegal to make Streams depend on System.  Then, having decided that
Streams needed its own type, we realized that it made sense for this
type to be of a different size than Storage_Element, at least on some
machines.

- Bob

****************************************************************

Questions? Ask the ACAA Technical Agent