CVS difference for ais/ai-00383.txt

Differences between 1.4 and version 1.5
Log of other versions for file ais/ai-00383.txt

--- ais/ai-00383.txt	2005/05/24 01:17:21	1.4
+++ ais/ai-00383.txt	2006/03/18 06:52:03	1.5
@@ -1,209 +1,23 @@
-!standard B.03(19)                                  05-05-23  AI95-00383/01
+!standard B.03(19)                                  05-05-23  AI95-00383/02
 !standard B.03(39)
 !class binding interpretation 04-08-31
+!status deleted 06-03-15
 !status work item 05-05-23
 !status received 04-08-31
 !priority Low
 !difficulty Medium
-!subject Unconstrained arrays and C interfacing
+!subject (Deleted)
 
 !summary
 
-We do not require support for conventions other than Ada for unconstrained
-array objects, unconstrained array function results, and most unconstrained
-array objects.
+The question of this AI is now covered by AI05-0002-1.
 
 !question
 
-The language requires support for C-compatible unconstrained array types
-(e.g. B.3(42) as applied to Interfaces.C.Char_Array). The correspondence
-described in B.3(70) applies to both constrained and unconstrained array types.
-This works fine in the Ada-calling-C direction, but not in the case of
-Ada-called-by-C. In the latter case, Ada is passed no information about the
-bounds of the array. How are Ada constructs which require bounds information
-supposed to work?
-
 !wording
 
-Replace B.1(17)
-
-    T is an access-to-object type and its designated type is L-compatible.
-
-with
-
-    T is an access-to-object type, its designated type is L-compatible,
-    and either its designated subtype is not an unconstrained array subtype
-    or L is Ada.
-
-Add after B.1(39) (in the Implementation Advice section):
-
-    The recommended level of support for an interfacing pragma specifying a
-    convention other than Ada or Intrinsic does not include the following cases:
-
-        - An interfacing pragma applied to an object whose nominal subtype is
-          an unconstrained array subtype.
-
-        - An Export or Convention pragma applied to a subprogram which has
-          a parameter of an unconstrained array subtype.
-
-        - An interfacing pragma applied to a function with
-          an unconstrained array result subtype.
-
-
 !discussion
 
-Consider the following example:
-
-  with Interfaces.C;
-  package Foo is
-    subtype Char_Array is Interfaces.C.Char_Array;
-    Buffer : Char_Array (1 .. 10) := "1234567890";
-    Renamed_Slice : Char_Array renames Buffer (3 .. 7);
-
-    procedure Proc1 (X : Char_Array);
-    pragma Export (C, Proc1, Link_Name => "proc1");
-  end Foo;
-
-  package body Foo is
-    procedure Proc1_Callback (X : Char_Array);
-    pragma Import (C, Proc1, Lin_Name => "proc1_callback");
-    --
-    -- Written in C, this routine takes a char* argument, which it passes
-    -- as the argument of a call to proc1.
-
-    procedure Assert (Condition : Boolean) is
-        Test_Failed : exception;
-    begin
-	if not Condition then
-	    raise Test_Failed;
-	end if;
-    end Assert;
-
-    procedure Proc1 (X : Char_Array) is
-	use type Char_Array;
-	use type Interfaces.C.Size_T;
-    begin
-	Assert (X'First = Renamed_Slice'First);
-	Assert (X'Last = Renamed_Slice'Last);
-	Assert (X = Renamed_Slice);
-    end Proc1;
-  begin
-    Proc1 (Renamed_Slice);
-    Proc1_Callback (Renamed_Slice);
-  end Foo;
-
-The current language rules don't provide any justification for rejecting this
-example, but it is not clear how it can be implemented.
-
-Compare this situation with the treatment of missing discriminants for
-Unchecked_Union types (AI-216). Discriminant checks are suppressed and each
-construct which would require accessing a missing discriminant is either
-statically illegal or is defined to raise Program_Error at runtime.
-It seems that an analogous set of rules is needed to handle this case.
-Just as "inferable discriminants" are defined for Unchecked_Union types,
-a corresponding definition of "inferable bounds" might make sense; on the other
-hand, this might not be worth the definitional complexity.
-
-A call (from Ada) to a convention-C function with an unconstrained array result
-presents much the same problem; the caller does not know the bounds of the
-function result.
-
-----
-
-The phrase "for a language" in B.1(12) means that nothing in B.1(12-19)
-applies in the case where L = Intrinsic. Thus, there is no need to mention
-the L = Intrinsic case in the revised B.1(17).
-
-----
-
-In the following example (for which support is recommended)
-
-    procedure Proc (X : String);
-    pragma Import (C, Proc, "Foobar");
-
-, it is expected that callers will pass in no bounds information.
-
-----
-
-There has been some concern expressed that under the terms of this proposal,
-it is not possible to write a portable program that (1) calls a C function
-that returns a String (a char*, really); or (2) implements a callback that
-has String (or equivalently Char_Array) parameters.
-
-It has never been possible to write portable code which uses these constructs;
-this proposal is only an explicit recognition of the existing state of affairs.
-
-Furthermore, this is not a big problem in practice. In most cases where no
-better solution is available, it suffices to declare a constrained array
-subtype (or an access type designating same) that is "big enough". For example,
-
-    subtype Big_String is Interfaces.C.Char_Array (0 .. 500000);
-
-    procedure P (X : Big_String);
-    pragma Export (C, P, "aabbcc");
-
-This imprecise representation need only be used until precise bounds
-information becomes available:
-
-    procedure P (X : Big_String) is
-       subtype S is Interfaces.C.Char_Array (0 .. Get_Length (X));
-       type S_Ref is access all S;
-       for S_Ref'Storage_Size use 0;
-
-       function Cvt is new Unchecked_Conversion (System.Address, S_Ref);
-       -- or use System.Address_To_Access_Conversions instead
-
-       X_With_Correct_Bounds : S renames Cvt (X'Address).all;
-       -- no subsequent references to X; use X_With_Correct_Bounds instead.
-
-
-It is true that this is somewhat cumbersome, but no better alternative has
-been proposed.
-
-One could explore the alternative of leaving the recommended level of
-support unmodified and instead working out a definition of the dynamic
-semantics of these constructs. Following the model of unchecked union
-types (whose discriminants are not represented at runtime), one could imagine
-"unchecked array" types (whose bounds are not represented at runtime).
-
-The notion of "inferable discriminants" could be generalized to include
-"inferable bounds" and much of the other wording from AI-216 would also
-carry over (e.g., discriminant check suppression => index check suppression).
-
-Unfortunately, the analogy breaks down in some important ways.
-
-All objects of a given unchecked union type are the same size.
-Thus, discriminant values are not needed in order to compute the size of an
-unchecked union object. There would be no way to compute the size of one of
-these "unchecked" array objects. This might be something fundamentally
-new for some compilers. At the very least, any operation which would normally
-require a size computation would have to be defined to raise Program_Error
-instead. This would affect assignment, concatenation, boolean vector operations,
-inherited constraints, etc.
-
-A call to a convention-Ada routine which expects to be passed a
-dope vector also could not be supported, nor could evaluation of
-bounds-related array attributes. Finally, the unsupported operations for
-unchecked union types listed in AI-216 would also be unsupported
-(i.e., equality testing, membership tests, conversion to a "normal" array type,
-and streaming attributes).
-
-Given that all these commonly used constructs would fail, it would
-be silly to claim that the language supports these "dopeless" array types.
-
-Furthermore, these failures would result in runtime errors whereas the
-proposed solution, while cumbersome, allows rejection of unsupported
-constructs at compile time.
-
-----
-
-Tuck reports that "We support unconstrained arrays as parameters in C
-conventions by giving the array the maximum bounds (i.e. index_subtype'first
-.. index_subtype'last)".
-
-Nothing in this proposal would prevent an implementation from choosing this
-approach.
-
 --!corrigendum
 
 !example
@@ -211,648 +25,4 @@
 !ACATS test
 
 !appendix
-
-From: Randy Brukardt
-Sent: Tuesday, August 31, 2004  6:02 PM
-
-Steve wrote:
-
-> The language requires support for C-compatible unconstrained array types
-> (e.g. B.3(42) as applied to Interfaces.C.Char_Array). The correspondence
-> described in B.3(70) applies to both constrained and unconstrained array types.
-> This works fine in the Ada-calling-C direction, but not in the case of
-> Ada-called-by-C. In the latter case, Ada is passed no information about the
-> bounds of the array. How are Ada constructs which require bounds information
-> supposed to work?
-
-Obviously, they don't. Since this is just Implementation Advice anyway, it can
-be ignored if it says something that is nonsense. Certainly, that is true in
-this case.
-
-We can also apply Dewar's rule here - the language says something stupid (C
-certainly can't call unconstrained arrays).
-
-Janus/Ada just rejects any pragma Import or Export that it doesn't know how to
-code generate. While I followed the IA as much as possible, I didn't sweat
-anything that I couldn't figure out... Still, the IA should be fixed (thus I
-opened an AI as noted above).
-
-...
->Compare this situation with the treatment of missing discriminants for
->Unchecked_Union types (AI-216). Discriminant checks are suppressed and each
->construct which would require accessing a missing discriminant is either
->statically illegal or is defined to raise Program_Error at runtime.
->It seems that an analogous set of rules is needed to handle this case.
->Just as "inferable discriminants" are defined for Unchecked_Union types,
->a corresponding definition of "inferable bounds" might make sense; on the other
->hand, this might not be worth the definitional complexity.
-
-Certainly not. We should just not allow such declarations; they cannot mean
-anything useful.
-
->A call (from Ada) to a convention-C function with an unconstrained array result
->presents much the same problem; the caller does not know the bounds of the
->function result.
-
-Right; this is the same problem.
-
-It should be noted that a legality rule would be OK here, because the rule
-would not need to depend on the representation of the unconstrained array:
-*all* unconstrained arrays should be banned in parameters of Export to C (and
-most other languages, too) and function returns of Import from C. But this rule
-probably should be IA as well, because we don't want to prevent an
-implementation from doing this if they can figure out some meaning for it.
-
-****************************************************************
-
-From: Tucker Taft
-Sent: Tuesday, August 31, 2004  8:21 PM
-
-We support unconstrained arrays as parameters in C conventions
-by giving the array the maximum bounds (i.e. index_subtype'first ..
-index_subtype'last).  Clearly there needs to be some other parameter
-which conveys the length, or some convention such as null termination.
-
-We have one customer who has requested a new convention, which
-we call "C_With_Array_Len" which adds an extra parameter in
-the C interface corresponding to the length of the array,
-so that the bounds become index_subtype'first .. index_subtype'first +
-len-param - 1.  If the array is multidimensional, a separate
-"len" parameter is added for each dimension.
-
-I'm not recommending this to be standardized, but it does indicate
-that some people are uncomfortable with our "standard" max-range
-approach.
-
-****************************************************************
-
-From: Robert Dewar
-Sent: Wednesday, September 1, 2004  8:39 AM
-
-Related to this is the issue that Address_To_Access conversions
-cannot work with unconstrained arrays.
-
-****************************************************************
-
-From: Randy Brukardt
-Sent: Wednesday, September 1, 2004  3:46 PM
-
-For the record, that's not strictly true; it works fine in Janus/Ada. But
-that's because we ignore Implementation Advice 13.3(14) [following it would
-have been incompatible with our Ada 83 compilers, and would have caused
-problems with some run-time code - as then there would be no way to access the
-array descriptors. It also would mean that it would be impossible to use an
-Address Clause with a constrained at creation array object.]. ('Address and
-'Access in Janus/Ada always point at the top-level object; for an array of size
-not known at compile-time, that's the array descriptor, not the data. The same
-is true for a component constrained by a discriminant.)
-
-But it's clearly not portable (and contrary to the mentioned IA), so it would
-make sense to discuss this case as well in the AI.
-
-****************************************************************
-
-From: Robert Dewar
-Sent: Wednesday, September 1, 2004  4:17 PM
-
-> For the record, that's not strictly true; it works fine in Janus/Ada. But
-> that's because we ignore Implementation Advice 13.3(14)
-
-Ouch! I would guess most of our customers big programs depend on that IA :-)
-
-> But it's clearly not portable (and contrary to the mentioned IA), so it
-> would make sense to discuss this case as well in the AI.
-
-Well if making something work means breaking some (really important in my
-view) IA, that's definitely an issue :-)
-
-What we do is to generate a warning that To_Pointer cannot be expected
-to be useful in this case:
-
-      3.    package A is new System.Address_To_Access_Conversions (String);
-            |
-         >>> warning: in instantiation at s-atacco.ads:45
-         >>> warning: Object is unconstrained array type
-         >>> warning: To_Pointer results may not have bounds
-
-In fact in GNAT the "may" is here because if the address was originally
-obtained by taking the address of a string, then the bounds may actually
-be where they are expected to be :-)
-
-****************************************************************
-
-From: Robert Dewar
-Sent: Wednesday, September 1, 2004  4:24 PM
-
-> We have one customer who has requested a new convention, which
-> we call "C_With_Array_Len" which adds an extra parameter in
-> the C interface corresponding to the length of the array,
-> so that the bounds become index_subtype'first .. index_subtype'first +
-> len-param - 1.  If the array is multidimensional, a separate
-> "len" parameter is added for each dimension.
->
-> I'm not recommending this to be standardized, but it does indicate
-> that some people are uncomfortable with our "standard" max-range
-> approach.
-
-Actually I think this is something that would be worth while
-semi-standardizing. GNAT tends to absorb such things anyway,
-so I think it might be worth including this as implementation
-advice. I trust it won't get too complicated (*).
-
-An alternative to having an extra parameter is to pass a descriptor.
-This is what is done in VMS for pass by descriptor.
-
-It also seems a shame to assume index_subtype'first, why not pass
-the bounds properly?
-
-(*) We just finished implementing the full blown Unchecked_Union.
-What a nightmare! And the sad thing is that our best guess is
-that none of the fancy extra features will get actually used :-(
-
-****************************************************************
-
-From: Tucker Taft
-Sent: Wednesday, September 1, 2004  4:48 PM
-
-> It also seems a shame to assume index_subtype'first, why not pass
-> the bounds properly?
-
-We are trying to present an interface that means something
-to a C programmer.  Arrays in C only have a length.  The
-low bound is always 0.  In Ada, the programmer gets to
-choose what is the more natural low bound (0, 1, whatever),
-but the C programmer needn't be bothered with this
-nicety.
-
-> (*) We just finished implementing the full blown Unchecked_Union.
-> What a nightmare! And the sad thing is that our best guess is
-> that none of the fancy extra features will get actually used :-(
-
-In our C code, we have many struct/union trees that match what
-the "full blown" Unchecked_Union is designed to support.
-For what that is worth...
-
-****************************************************************
-
-From: Robert Dewar
-Sent: Wednesday, September 1, 2004  5:14 PM
-
-Tucker Taft wrote:
-
-> In our C code, we have many struct/union trees that match what
-> the "full blown" Unchecked_Union is designed to support.
-> For what that is worth...
-
-But C unions don't allow more than one component in each variant!
-
-Also, it is not the data layout that is the issue, it is all the
-special casees of allowing things like equality when you can figure
-out the discriminants.
-
-Did you implement this feature fully yet?
-
-****************************************************************
-
-From: Pascal Leroy
-Sent: Thursday, September 2, 2004  7:38 AM
-
-If we are in the business of fixing A_To_A_Conversion, I would be in favor
-of making the access type a formal type (I know, for compatibility a new
-generic would be required).  It is totally dumb that each instantiation of
-this generic creates a collection, for which you cannot specify the
-storage size.
-
-****************************************************************
-
-From: Robert A. Duff
-Sent: Thursday, September 2, 2004  7:56 AM
-
-Mea Culpa.  I wrote that section.  I did it that way on purpose, but
-after having used the thing a few times, I realized it is, as you say,
-"totally dumb".  But I don't think it's important enough to bother
-fixing.
-
-****************************************************************
-
-From: Robert Dewar
-Sent: Friday, September 3, 2004  3:14 AM
-
-Indeed! This is a fundamental inconsistency which should be fixed. moreover
-you cannot specify a storage pool, which is even worse.
-
-****************************************************************
-
-From: Tucker Taft
-Sent: Friday, September 3, 2004  7:19 AM
-
-I'm not sure I understand the concern here.  The generic
-is intended to provide an access value given an address.
-It was never expected that such an access value would
-be considered equivalent to an access value created by
-an allocator.  This generic is more like GNAT's
-'Unrestricted_Access. So what possible meaning would
-there be for the storage size or storage pool, since those
-attributes are relevant only for allocators (and unchecked
-deallocation)?
-
-****************************************************************
-
-From: Tucker Taft
-Sent: Friday, September 3, 2004  8:20 AM
-
-I might add that anonymous access types, which we are
-now allowing in more contexts, have the same property
-of not allowing the specification of storage size or
-storage pool.  So this all sounds like a tempest
-in a teapot to me.  Do people really have a bunch
-of these A_To_A instantiations all over the place?
-
-****************************************************************
-
-From: Robert A. Duff
-Sent: Friday, September 3, 2004  8:58 AM
-
-I agree that it's a tempest in a tea pot.
-
-I think the issue is not Storage_Pool per se.  The issue is that if you
-have an access type, and you want to convert an Address value to that
-type, you have to call the To_Pointer function from the instance, and
-then convert *that* to your access type, using a normal type conversion.
-It would be slightly cleaner to be able to convert directly.
-
-So why don't you just use the access type declared in the instance of
-Address_To_Access_Conversions?  I think Pascal was saying, "Because I
-want a Storage_Size clause", and Robert was saying, "Yeah, and because I
-want a Storage_Pool clause."  Another obvious reason is that your access
-type belongs in a package spec, and the instance belongs in the body.
-
-I still say: it's not broken enough to fix.  Just put in the silly extra
-type conversion.  One hopes not to use this feature very often!
-
-By the way, why would you want to use Address_To_Access_Conversions to
-go the other direction?  I mean, isn't X.all'Address sufficient?
-(I usually don't want nulls in these cases...)
-
-P.S. The reason I didn't do it Pascal's way in the first place, is that
-I imagined the only usage would be for "peek/poke" functionality.  That
-is, I thought you would always do something like this:
-
-    Thing: Integer renames To_Pointer(Some_Address).all;
-
-    Thing := Thing + 1;
-
-with an immediate .all, and you don't care what the access type is.
-Declaring one and passing it to the instantiation is just annoying
-verbosity in this case.
-(In fact, you want an anonymous access type!)
-
-****************************************************************
-
-From: Robert Dewar
-Sent: Friday, September 3, 2004  3:54 PM
-
-Well I think it would be reasonable to have a note in the RM noting
-the case that is unlikely to work, or rather unlikely to work in
-anything approximating a portable manner.
-
-> I think the issue is not Storage_Pool per se.  The issue is that if you
-> have an access type, and you want to convert an Address value to that
-> type, you have to call the To_Pointer function from the instance, and
-> then convert *that* to your access type, using a normal type conversion.
-> It would be slightly cleaner to be able to convert directly.
-
-Can you say what you mean here, you can't just go converting access
-types when storage pools are involved???
-
-****************************************************************
-
-From: Randy Brukardt
-Sent: Friday, September 3, 2004  7:12 PM
-
-While I generally agree with you and Pascal on this topic, I don't understand
-the above. There is no restriction on converting between general access types
-as long as they designate the same type. The only problem comes if you call
-Unchecked_Deallocation on an access from another pool; that's defined to be
-erroneous in 13.11.2(16).
-
-Even if you had an A_to_A that allowed an access type with a pool, I would hope
-that using Unchecked_Deallocation on the result would still be erroneous. (It
-certainly wouldn't be meaningful unless it was previous allocated from that
-pool - in which case, why the heck do you need A_to_A??) So there isn't going
-to be any semantic difference here.
-
-The real issue to me is that we expanded the use of anonymous access types
-specifically so we could get rid of unnecessary explicit conversions, as
-they're confusing to the reader (a type conversion is supposed to indicate
-something happening). This is another source of unnecessary conversions, and it
-would make sense to get rid of them here as well.
-
-****************************************************************
-
-From: Robert A. Duff
-Sent: Friday, September 3, 2004  7:30 PM
-
-> Well I think it would be reasonable to have a note in the RM noting
-> the case that is unlikely to work, or rather unlikely to work in
-> anything approximating a portable manner.
-
-You mean the access-to-unc-array case?  Yeah, a note seems reasonable.
-
-> > I think the issue is not Storage_Pool per se.  The issue is that if you
-> > have an access type, and you want to convert an Address value to that
-> > type, you have to call the To_Pointer function from the instance, and
-> > then convert *that* to your access type, using a normal type conversion.
-> > It would be slightly cleaner to be able to convert directly.
->
-> Can you say what you mean here, you can't just go converting access
-> types when storage pools are involved???
-
-The package as currently defined:
-
-      generic
-          type Object(<>) is limited private;
-      package System.Address_To_Access_Conversions is
-         pragma Preelaborate(Address_To_Access_Conversions);
-
-         type Object_Pointer is access all Object;
-         function To_Pointer(Value : Address) return Object_Pointer;
-         ...
-      end System.Address_To_Access_Conversions;
-
-I thought Pascal's proposal was to change it to:
-
-      generic
-          type Object(<>) is limited private;
-          type Object_Pointer is access all Object;
-      package System.Address_To_Access_Conversions is
-         pragma Preelaborate(Address_To_Access_Conversions);
-
-         function To_Pointer(Value : Address) return Object_Pointer;
-         ...
-      end System.Address_To_Access_Conversions;
-
-That is, make the pointer type into a generic formal.
-
-With the current language, one can do this:
-
-    package Things is
-        type Thing is ...
-        type Thing_Ptr is access all Thing;
-        for Thing_Ptr'Storage_Pool use ...;
-        ...
-    end Things;
-
-    with System.Address_To_Access_Conversions;
-    package body Things is
-        package Conv is new System.Address_To_Access_Conversions(Thing);
-
-        function F(...) return Thing_Ptr is
-        begin
-            return Thing_Ptr(Conv.To_Pointer(Some_Address));
-
-With Pascal's proposal, the body becomes:
-
-    with System.Address_To_Access_Conversions;
-    package body Things is
-        package Conv is new
-            System.Address_To_Access_Conversions(Thing, Thing_Ptr);
-
-        function F(...) return Thing_Ptr is
-        begin
-            return Conv.To_Pointer(Some_Address);
-
-That is, the type conversion to Thing_Ptr is eliminated.  Either way, Thing_Ptr
-can have a Storage_Pool or Storage_Size clause.  And either way, the programmer
-had better ensure that Some_Address "makes sense" as a value of type Thing_Ptr.
-And either way, if you try to use Unchecked_Dealloc, you better make
-sure it originally came from the same pool.
-
-****************************************************************
-
-From: Robert A. Duff
-Sent: Friday, September 3, 2004  7:41 PM
-
-> While I generally agree with you and Pascal on this topic, I don't
-> understand the above. There is no restriction on converting between general
-> access types as long as they designate the same type. The only problem comes
-> if you call Unchecked_Deallocation on an access from another pool; that's
-> defined to be erroneous in 13.11.2(16).
-
-Right.
-
-> Even if you had an A_to_A that allowed an access type with a pool, I would
-> hope that using Unchecked_Deallocation on the result would still be
-> erroneous.
-
-Yes.
-
->... (It certainly wouldn't be meaningful unless it was previous
-> allocated from that pool - in which case, why the heck do you need A_to_A??)
-
-If you're playing games with storage pools, you might have a function
-that allocates some storage, and returns a pointer to that storage plus
-some offset.  And deallocate might need to recover the original storage
-pointer by subtracting that offset.  I've done something like that in
-low-level storage-pool code, where *this* storage pool is allocating
-hunks of storage from an underlying storage pool.
-
-> So there isn't going to be any semantic difference here.
-
-Right.
-
-> The real issue to me is that we expanded the use of anonymous access types
-> specifically so we could get rid of unnecessary explicit conversions, as
-> they're confusing to the reader (a type conversion is supposed to indicate
-> something happening). This is another source of unnecessary conversions, and
-> it would make sense to get rid of them here as well.
-
-Right.  So should it be:
-
-      generic
-          type Object(<>) is limited private;
-      package System.Address_To_Access_Conversions is
-         pragma Preelaborate(Address_To_Access_Conversions);
-
-         function To_Pointer(Value : Address) return access all Object;
-         ...                                         ^^^^^^^^^^^^^^^^^
-      end System.Address_To_Access_Conversions;
-
-where the result of To_Pointer can be *implicitly* converted to whatever
-appropriate access type you like?  Or something like that?
-
-****************************************************************
-
-From: Pascal Leroy
-Sent: Monday, September 6, 2004  4:00 AM
-
-Well, it's nice to reduce the number of implicit conversions, but it
-doesn't solve the problem I had in mind.
-
-Say that I am getting an address from some low-level mechanism, e.g.
-calling a C library.  I want to convert this address into an Ada
-access-to-record, to access individual fields in a type-safe manner.
-There are various useful properties that I am unable to express in Ada
-because the silly A_To_A_Conversion insists on declaring the access type
-itself:
-
-1 - I am not going to change the allocated structure; I'd like to have an
-access-to-constant.
-2 - I am not going to do any allocation on the Ada side; I'd like to have
-storage size of 0.
-3 - I may be doing allocations/deallocations on the Ada side, but they
-better go through the storage management mechanism provided by the C
-library, lest plague and pestilence ensue; I'd like to specify a storage
-pool.
-
-All three would be possible to express if the generic took an access type
-as a parameter (OK, we would need two generics for access-to-constant and
-access-to-variable).  And please don't tell me that I can just convert the
-access type exported by the instantiation to a user-declared one with the
-right properties, because that doesn't give me any additional safety: I
-cannot prevent code from writing/allocating/deallocating through the type
-exported by the instantiation.
-
-****************************************************************
-
-From: Robert A. Duff
-Sent: Monday, September 6, 2004  8:48 AM
-
-> All three would be possible to express if the generic took an access type
-> as a parameter (OK, we would need two generics for access-to-constant and
-> access-to-variable).
-
-The above are all true.  I just don't think it's important enough to
-fix.
-
->...And please don't tell me that I can just convert the
-> access type exported by the instantiation to a user-declared one with the
-> right properties,...
-
-Too late.   ;-)  I already told you that.
-
->...because that doesn't give me any additional safety: I
-> cannot prevent code from writing/allocating/deallocating through the type
-> exported by the instantiation.
-
-Well, you can work around that by instantiating in a fairly invisible
-place.  E.g.
-
-    function To_Ptr(X: System.Address) return Some_Ptr is
-        package Instance is new A_To_A_Conversions(...);
-    begin
-        return Some_Ptr(Instance.To_Pointer(X));
-    end To_Ptr;
-
-Or leave out Some_Ptr() if the conversion is implicit.
-
-These annoyances would bother me more if A_To_A_C were something I use
-every day.  I must admit that I've used Unchecked_Conversion instead,
-sometimes.
-
-****************************************************************
-
-From: Robert I. Eachus
-Sent: Monday, September 6, 2004  11:46 AM
-
-"Fixing" this issue would in my mind be a bad idea.  It would add an
-unnecessary upward incompatibility to the language. But adding separate
-children of System that takes access parameters may be worth doing.  The
-question for implementors is whether or not adding the the following
-package to the standard would require much if any work:
-
- generic
-    type Object(<>) is limited private;
-    type Object_Pointer is access all Object;
- package System.Address_To_Named_Access_Conversions is
-    pragma Preelaborate(Address_To_Named_Access_Conversions);
-
-    function To_Pointer(Value : Address) return access all Object;
-    function To_Address(Value : Object_Pointer) return Address;
-
-    pragma Convention(Intrinsic, To_Pointer);
-    pragma Convention(Intrinsic, To_Address);
-
- end System.Address_To_Named_Access_Conversions;
-
- generic
-    type Object(<>) is limited private;
-    type Object_Pointer is access constant Object;
- package System.Address_To_Constant_Access_Conversions is
-    pragma Preelaborate(Address_To_Constant_Access_Conversions);
-
-    function To_Pointer(Value : Address) return access constant Object;
-    function To_Address(Value : Object_Pointer) return Address;
-    pragma Convention(Intrinsic, To_Pointer);
-    pragma Convention(Intrinsic, To_Address);
-
- end System.Address_To_Constant_Access_Conversions;
-
-My guess is that the work required would be mostly cut and paste (as would the
-work in the RM), so it may be easier to add these packages than to continue the
-debate.
-
-****************************************************************
-
-From: Robert A. Duff
-Sent: Monday, September 6, 2004  12:33 PM
-
-By "fixing", I meant "adding separate children...", which is exactly
-what Pascal suggested.  But note that Pascal or any other programmer
-can implement the desired functionality in plain portable Ada 95:
-
- generic
-    type Object(<>) is limited private;
-    type Object_Pointer is access all Object;
- package System.Address_To_Named_Access_Conversions is
-    pragma Preelaborate(Address_To_Named_Access_Conversions);
-
-    function To_Pointer(Value : Address) return Object_Pointer;
-    function To_Address(Value : Object_Pointer) return Address;
-
-    pragma Inline(To_Pointer);
-    pragma Inline(To_Address);
-
- end System.Address_To_Named_Access_Conversions;
-
- with Address_To_Access_Conversions;
- package System.Address_To_Named_Access_Conversions is
-
-    package A_To_A is new Address_To_Access_Conversions(Object);
-
-    function To_Pointer(Value : Address) return return Object_Pointer is
-    begin
-        return Object_Pointer(A_To_A.To_Pointer(Value));
-    end To_Pointer;
-
-    function To_Address(Value : Object_Pointer) return Address is
-    begin
-        return Value.all'Address;
-OR (if you want to allow nulls):
-	return To_Address(A_To_A.Object_Pointer(Value));
-    end To_Address;
-
- end System.Address_To_Named_Access_Conversions;
-
-and similarly for the access-constant version.
-
-****************************************************************
-
-From: Robert Dewar
-Sent: Monday, September 6, 2004  12:50 PM
-
-This is not portable Ada, you can't go adding children to
-System yourself!
-
-****************************************************************
-
-From: Robert A. Duff
-Sent: Monday, September 6, 2004  2:08 PM
-
-Got me!
-
-I forgot to delete "System." from the example.  I did remember to change
-pragma Intrinsic to pragma Inline.  ;-)
-
-****************************************************************
 

Questions? Ask the ACAA Technical Agent