Version 1.4 of ais/ai-00097.txt

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

!standard RM-4.6 (47)          00-01-25 AI95-00097/07
!class confirmation 95-09-29
!status Response 2000 00-01-25
!status WG9 approved 96-12-07
!status ARG approved 10-0-2 96-10-07
!status ARG approved 6-1-1 (subject to editorial review) 96-06-17
!status work item 95-11-01
!status received 95-09-29
!priority High
!difficulty Medium
!qualifier Omission
!subject Conversions between access types with different representations.
!summary
If the Convention (other than Ada) of an access type has been specified by the user, then the semantics of type conversions involving that access type are implementation defined.
!question
It is possible to declare types that are normally convertible, but that have a pragma Convention that makes some such conversions impossible or impractical. For instance,
type Ada_Ptr is access Integer; -- Integer is C-compatible in this -- implementation. type C_Ptr is new Ada_Ptr; pragma Convention (C, C_Ptr);
The value sets of such convertible types may not completely overlap. For example, on a machine that is not 8-bit-byte addressable, an Ada_Ptr might be represented as a normal address, whereas a C_Ptr might be represented as a bit-field pointer of some sort.
What should happen when a value of C_Ptr has no corresponding value in Ada_Ptr?
!response
The semantics of such conversions are implementation defined. This follows from the fact that pragma Convention is a representation pragma (B.1(29)), and implementations can interpret representation pragmas however they want and place restrictions on them (13.1(20)), except when there are explicit rules to the contrary. This is also stated in the NOTE of B.1(43). So it's perfectly acceptable to raise an exception when a given operation doesn't make sense.
This is clearly desirable, since the goal of interfacing to another language is to match the representations chosen by the implementation of the other language, and doing so can make it impossible or impractical to obey the "normal" (non-interfaced) Ada semantics.
!ACATS test
No test is possible. This AI gives a permission for implementation-defined semantics, which of course cannot be tested in a portable way.
!appendix

!section RM-4.6(47)
!subject Conversions between access types with different representations.
!reference RM95-4.6(47-50)
!reference RM95-B.1(12-20)
!from Randy Brukardt 95-09-19
!reference as: 95-5302.a rbrukardt@BIX.com 95-9-19>>
!discussion

The introduction of the Convention pragma makes it possible, and in some cases
necessary, for an implementation to support multiple representations for
access types.

Two examples are the long/short pointers of the 8086, and the many different
kinds of pointer found on the Unisys 2200s.

It is possible to declare types such that the compiler will generate the
needed conversions between them.  For instance,

        Type Ada_Ptr Is Access Integer; -- Integer is C-compatible in this
                                        -- implementation.
        Type C_Ptr Is New Ada_Ptr;
        Pragma Convention (C, C_Ptr);

The value sets of such convertable types may not completely overlap.

What should happen when a value of C_Ptr has no corresponding value in Ada_Ptr?

That is, given:
        A : A_Ptr;
        C : C_Ptr;

        C := C_Malloc(10);
        A := Ada_Ptr(C); -- What happens here if A cannot point at what C points at?

The answers seem to be:
1) Constraint_Error.  But 4.6(47-50) does not given any permission to raise
Constraint_Error on a access type conversion.

2) Program_Error.  However, the program is not erroneous (the value of C is
initialized, and is a valid value of that type).  Using A after the conversion
would be erroneous, but the conversion itself seems to be legal.

3) No error can be raised.  That means the value of A will not access the same
object as C.  It is likely to be much harder to detect the error afterwards,
and seems to be counter to the Ada philosophy to ignore an easily checked
error.

4) The conversion is illegal because the type declarations are illegal.  This
would mean that there would be no way within Ada to convert between various
access representations.  A series of unchecked_conversions and
implementation-defined functions would have to be used, damaging portability
and making code much harder to read.

(Side note: Of course, all such errors cannot be cheaply detected.  However
many such errors can be cheaply detected, and a compiler that wants to do so
certainly should be allowed to do so.)

In the specific case of the Unisys 2200 compiler, we are using different
representations for access types and C pointer simply because the C pointers
are expensive, since they have to be able to point into the middle of a word.
(Characters are packed 4 to a word on this machine; C of course must be able
to point at an individual character; Ada does not need this capability).

While this sort of conversion is not common, it does happen in practice.  For
instance, the default storage pool is written in C; the returned pointers are
known to be aligned (at least, they are supported to be aligned!), and need to
be converted into the Ada representation.

For the moment, we are raising Program_Error; the check can be suppressed if
need be.

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

!section 4.6(47)
!subject Conversions between access types with different representations.
!reference RM95-4.6(47-50)
!reference RM95-B.1(12-20)
!reference 95-5302.a rbrukardt@BIX.com 95-9-19
!from Bob Duff
!reference as: 95-5308.a Robert A Duff 95-9-29>>
!discussion

> It is possible to declare types such that the compiler will generate the
> needed conversions between them.  For instance,
>
>       Type Ada_Ptr Is Access Integer; -- Integer is C-compatible in this
>                                       -- implementation.
>       Type C_Ptr Is New Ada_Ptr;
>       Pragma Convention (C, C_Ptr);
>
> The value sets of such convertable types may not completely overlap.
>
> What should happen when a value of C_Ptr has no corresponding value in Ada_Ptr?

It seems to me that this is implementation defined.  This follows from
the fact that pragma Convention is a representation pragma
(RM95-B.1(29)), and implementations can interpret representation pragmas
however they want and place restrictions on them (13.1(20)), except when
there are explicit rules to the contrary.  This is also stated in the
NOTE of B.1(43).  So, I think it's perfectly acceptable to raise an
exception when a given operation doesn't make sense.

I suggest that in the case you mention, you raise Program_Error.

- Bob

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

Questions? Ask the ACAA Technical Agent