CVS difference for ais/ai-00279.txt

Differences between 1.12 and version 1.13
Log of other versions for file ais/ai-00279.txt

--- ais/ai-00279.txt	2005/02/08 07:12:28	1.12
+++ ais/ai-00279.txt	2005/06/16 23:47:21	1.13
@@ -243,13 +243,13 @@
 @drepl
 @xindent<First reads the external tag from @i<Stream> and determines the
 corresponding internal tag (by calling Tags.Internal_Tag(String'Input(@i<Stream>))
--- ches to the subprogram denoted by the Input
+@emdash see 3.9) and then dispatches to the subprogram denoted by the Input
 attribute of the specific type identified by the internal tag; returns that
 result.>
 @dby
 @xindent<First reads the external tag from @i<Stream> and determines the
 corresponding internal tag (by calling
-Tags.Internal_Tag(String'Input(@i<Stream>)) -- see 3.9) and then dispatches to
+Tags.Internal_Tag(String'Input(@i<Stream>)) @emdash see 3.9) and then dispatches to
 the subprogram denoted by the Input attribute of the specific type identified
 by the internal tag; returns that result. If the specific type identified by
 the internal tag is not covered by T'Class or is abstract, Constraint_Error is
@@ -278,10 +278,10 @@
 !corrigendum 13.13.2(38)
 
 @dinsa
-@xindent<@s9<32 User-specified attributes of S'Class are not inherited by other
+@xindent<@s9<32  User-specified attributes of S'Class are not inherited by other
 class-wide types descended from S.>>
 @dinst
-@xindent<@s9<33 If the prefix subtype S of function S'Class'Input is a library-level
+@xindent<@s9<33  If the prefix subtype S of function S'Class'Input is a library-level
 subtype, then reading a value of a type which has not yet been frozen with the
 S'Class'Input function will always raise Tag_Error; execution cannot be
 erroneous.>>
@@ -702,3 +702,199 @@
 implementations which allocate tags dynamically.
 
 ****************************************************************
+
+!topic Questions about external tags
+!reference RM06 3.9
+!from Adam Beneschan 05-05-04
+!discussion
+
+I have some questions related to external tags, Internal_Tag, and
+Descendant_Tag:
+
+1) Both AI-344 and AI-279 indicate that the phrase "The function
+   Internal_Tag returns the tag ..." will be changed to "The function
+   Internal_Tag returns a tag ..."  The RM version available through
+   "Ada 2006 working documents" does not have this change.  May I
+   assume that this word will be changed at some point?
+
+2) Assuming that the word "a" is correct, then 3.9(12/2) starts out,
+   "The function Internal_Tag returns a tag that corresponds to the
+   given external tag".  "corresponds" is a pretty vague term.  Is
+   this phrase exactly equivalent to, "The function Internal_Tag, when
+   called with parameter External, returns a tag T such that
+   External_Tag(T)=External"?  Or are there some other semantics
+   involved?
+
+3) I'm a little confused about what the status of a type is when the
+   type is defined by a master, and then the master is left.  Does the
+   type still exist, in some sense?
+
+   The reason I'm asking is because of the way Descendant_Tag is
+   defined by 3.9(12.1/2):
+
+     The function Descendant_Tag returns the (internal) tag for the
+     type that corresponds to the given external tag and is both a
+     descendant of the type identified by the Ancestor tag
+
+   Suppose a procedure Proc defines a nested tagged type (or tagged
+   extension) T1.  Somewhere inside Proc, we set "X := T1'Tag", where
+   X is a global variable of type Ada.Tags.Tag.  Then, we leave Proc.
+   Somewhere else, we use X as the Ancestor parameter to
+   Descendant_Tag.
+
+   What is the result?  If the type T1 no longer exists, this causes a
+   problem, since the definition of Descendant_Tag assumes that there
+   is a type identified by Ancestor, and doesn't allow for the
+   possibility that there is no such type.  If T1 does exist in some
+   sense that's usable by Descendant_Tag, then what are the semantics
+   of Descendant_Tag in that case?
+
+   Supposing that Proc is recursive, and Proc calls itself.  The inner
+   Proc saves T1'Tag in a global Ada.Tags.Tag variable X.  The inner
+   Proc then exits.  The outer Proc uses X as the ancestor parameter
+   to Descendant_Tag.  What should happen?  Are implementations
+   expected to check that Ancestor is the tag for a type that no
+   longer exists?
+
+   I realize this is all pretty pathological and unlikely to occur in
+   practice.  (I don't see any way that the above pathological calls
+   to Descendant_Tag could be generated by T'Class'Input.)  But I
+   think something has to be defined, even if it's just defined as
+   "Erroneous Execution".
+
+****************************************************************
+
+From: Randy Brukardt
+Date: Wednesday, May 4, 2005  5:43 PM
+
+Adam Beneschan wrote:
+
+> 1) Both AI-344 and AI-279 indicate that the phrase "The function
+>    Internal_Tag returns the tag ..." will be changed to "The function
+>    Internal_Tag returns a tag ..."  The RM version available through
+>    "Ada 2006 working documents" does not have this change.  May I
+>    assume that this word will be changed at some point?
+
+That's obviously a typo, and I've fixed it in next draft.
+
+> 2) Assuming that the word "a" is correct, then 3.9(12/2) starts out,
+>    "The function Internal_Tag returns a tag that corresponds to the
+>    given external tag".  "corresponds" is a pretty vague term.  Is
+>    this phrase exactly equivalent to, "The function Internal_Tag, when
+>    called with parameter External, returns a tag T such that
+>    External_Tag(T)=External"?  Or are there some other semantics
+>    involved?
+
+I think it is very intentional that it is vague. :-) We concluded that
+Internal_Tag has no well-defined semantics once AI-344 exists, (which is why
+we have Descendant_Tag). It's really an obsolete function kept for
+compatibility. I'd expect an implementation do so the same thing that it
+does for Ada 95 for Ada 95 possible tags (other than raising Tag_Error as
+needed), for other tags, do whatever makes sense. Anyone using Internal_Tag
+on a non-library-level tag gets what they deserve (an answer which probably
+will vary by implementation). So this is a function who's implementation is
+only wrong if it fails to do something sensible. (Do implementers really
+want this to harm their users by doing something useless??)
+
+> 3) I'm a little confused about what the status of a type is when the
+>    type is defined by a master, and then the master is left.  Does the
+>    type still exist, in some sense?
+
+Types never really disappear in Ada. Only subtypes (the names of the types)
+disappear. But there is a point after which you really don't want to be
+using a composite type that has internal dynamic constraints.
+
+>    The reason I'm asking is because of the way Descendant_Tag is
+>    defined by 3.9(12.1/2):
+>
+>      The function Descendant_Tag returns the (internal) tag for the
+>      type that corresponds to the given external tag and is both a
+>      descendant of the type identified by the Ancestor tag
+>
+>    Suppose a procedure Proc defines a nested tagged type (or tagged
+>    extension) T1.  Somewhere inside Proc, we set "X := T1'Tag", where
+>    X is a global variable of type Ada.Tags.Tag.  Then, we leave Proc.
+>    Somewhere else, we use X as the Ancestor parameter to
+>    Descendant_Tag.
+>
+>    What is the result?  If the type T1 no longer exists, this causes a
+>    problem, since the definition of Descendant_Tag assumes that there
+>    is a type identified by Ancestor, and doesn't allow for the
+>    possibility that there is no such type.  If T1 does exist in some
+>    sense that's usable by Descendant_Tag, then what are the semantics
+>    of Descendant_Tag in that case?
+
+Either the tag ought to work (and provide the normal answer), or it should
+raise Tag_Error, as allowed by 3.9(26).
+
+If tags are statically allocated entities (as usual in Ada 95), then they
+ought to continue to work. (It's hard to imagine why they wouldn't.) If,
+however, they're dynamic in some sense, then presumably they are registered
+with the implementation (to provide the needed lookup table), and they ought
+to be de-registered when their master goes away. In which case detection
+should be trivial.
+
+We purposely do not select which of these implementations is used.
+
+>    Supposing that Proc is recursive, and Proc calls itself.  The inner
+>    Proc saves T1'Tag in a global Ada.Tags.Tag variable X.  The inner
+>    Proc then exits.  The outer Proc uses X as the ancestor parameter
+>    to Descendant_Tag.  What should happen?  Are implementations
+>    expected to check that Ancestor is the tag for a type that no
+>    longer exists?
+
+Same as above. Note that tags don't necessarily have to be distinct for
+recursive calls. See the "To Be Honest" in 3.9(4.c).
+
+>    I realize this is all pretty pathological and unlikely to occur in
+>    practice.  (I don't see any way that the above pathological calls
+>    to Descendant_Tag could be generated by T'Class'Input.)  But I
+>    think something has to be defined, even if it's just defined as
+>    "Erroneous Execution".
+
+We've discussed this extensively, and we believe that there aren't any
+problems in actual practice. Either 3.9(26) applies and is relatively easy
+to implement, or the natural implementation works well enough. (Obviously,
+no one is going to be checking for specific answers in these cases; just no
+destruction of the universe.) If the tag comes from outside of the partition
+(not from a call of 'Tag), then it is going to be abnormal, for which any
+use is erroneous.
+
+Trying to nail down these semantics more closely simply would trigger a war
+about implementation strategies, or make most uses of these routines
+erroneous (which is not acceptable).
+
+****************************************************************
+
+From: Adam Beneschan
+Date: Wednesday, May 4, 2005  6:11 PM
+
+> Either the tag ought to work (and provide the normal answer), or it should
+> raise Tag_Error, as allowed by 3.9(26).
+
+Drat.  I looked everywhere in 3.9 except this paragraph.  That would
+have answered my question.
+
+Sigh . . .
+
+****************************************************************
+
+From: Gary Dismukes
+Date: Thursday, May 4, 2005  11:56 AM
+
+Btw, I noticed there's a small typo in the next to last sentence of
+AARM-3.9(26.a/2) (longer => no longer):
+
+In that case, Tag_Error could also be raised if the created type {no} longer
+exists because the subprogram containing it has returned, for example.
+
+****************************************************************
+
+From: Randy Brukardt
+Date: Thursday, May 4, 2005  12:22 PM
+
+Thanks for noting that. I see that the Ada 95 version is correct; I wonder
+what happened to that word? Anyway, it's fixed.
+
+****************************************************************
+

Questions? Ask the ACAA Technical Agent