!standard 13.9.1(12/2) 11-11-13 AI05-0279-1/01 !class binding interpretation 11-11-13 !status Amendment 2012 11-11-13 !status ARG Approved 7-0-0 11-11-13 !status work item 11-11-13 !status received 11-11-09 !priority Low !difficulty Medium !qualifier Omission !subject Renaming an invalid Unchecked_Conversion result !summary A rename of an invalid Unchecked_Conversion function call does not, by itself, cause erroneous execution. !question The rules in 13.9.1(12/2) do not appear to allow the renaming of an invalid Unchecked_Conversion result without causing erroneous execution. That's because the result is "used other than...". If we are going to allow assignment of invalid values in these restricted cases, then we ought to allow the equivalent approach of renaming the function result. Should this be allowed? (Yes.) !recommendation (See summary.) !wording Modify 13.9.1(12/2): A call to an imported function or an instance of Unchecked_Conversion is erroneous if the result is scalar, and the result object has an invalid representation, and the result is used other than as the expression of an assignment_statement or an object_declaration,{ as the object_name of an object_renaming_declaration,} or as the prefix of a Valid attribute. If such a result object is used as the source of an assignment, and the assigned value is an invalid representation for the target of the assignment, then any use of the target object prior to a further assignment to the target object, other than as the prefix of a Valid attribute reference, is erroneous. !discussion While the rename of an invalid Unchecked_Conversion function call does not cause erroneous execution, further usage of the object via its new name might. The rules are defined in terms of the result object, and thus the name used to reference that object is irrelevant. [Editor's note: I almost wrote "moot" here just to tweak Robert. :-)] That is why we don't need any special rules to describe what happens when the function result is renamed; that just provides a new name for the object. !corrigendum 13.9.1(12/2) @drepl A call to an imported function or an instance of Unchecked_Conversion is erroneous if the result is scalar, the result object has an invalid representation, and the result is used other than as the @fa of an @fa or an @fa, or as the @fa of a Valid attribute. If such a result object is used as the source of an assignment, and the assigned value is an invalid representation for the target of the assignment, then any use of the target object prior to a further assignment to the target object, other than as the @fa of a Valid attribute reference, is erroneous. @dby A call to an imported function or an instance of Unchecked_Conversion is erroneous if the result is scalar, the result object has an invalid representation, and the result is used other than as the @fa of an @fa or an @fa, as the @i@fa of an @fa, or as the @fa of a Valid attribute. If such a result object is used as the source of an assignment, and the assigned value is an invalid representation for the target of the assignment, then any use of the target object prior to a further assignment to the target object, other than as the @fa of a Valid attribute reference, is erroneous. !ACATS Test An ACATS C-Test should be created (but this is likely to be low priority). !ASIS No ASIS effect. !appendix From: Steve Baird Sent: Wednesday, November 9, 2011 11:32 AM RM 13.9.1(12) says: A call to an imported function or an instance of Unchecked_Conversion is erroneous if the result is scalar, and the result object has an invalid representation, and the result is used other than as the expression of an assignment_statement or an object_declaration, or as the prefix of a Valid attribute. If such a result object is used as the source of an assignment, and the assigned value is an invalid representation for the target of the assignment, then any use of the target object prior to a further assignment to the target object, other than as the prefix of a Valid attribute reference, is erroneous. It seems clear to me that if we are going to allow assignment of invalid values in these restricted cases, then we certainly ought to allow the cleaner (in the sense that no assignment operations and no subtype conversions are involved once the function has returned) approach of renaming the function result. To illustrate, given function Cvt is new Unchecked_Conversion (Some_Type, Integer); I would prefer (for reasons of cleanliness, given above) Converted : Integer renames Cvt (...); begin if Converted'Valid then ... to either function Cvt is ,,,; Converted : constant Integer := Cvt (...); begin if Converted'Valid then ... or Converted : Integer; begin Converted := Cvt (...); if Converted'Valid then ... Unfortunately, it appears that the RM wording above doesn't allow renaming the function result. The rename runs afoul of the "and the result is used other than as " clause. I believe that this is a language design flaw, and one that is significant enough to warrant fixing. Randy Brukardt wrote: > Looks like a hole. I don't think anyone considered renames with this > wording. Ask for an Ada2012 AI. I'm asking. **************************************************************** From: Robert Dewar Sent: Wednesday, November 9, 2011 5:10 PM > It seems clear to me that if we are going to allow assignment of > invalid values in these restricted cases, then we certainly ought to > allow the cleaner (in the sense that no assignment operations and no > subtype conversions are involved once the function has returned) > approach of renaming the function result. I must say I hate the whole notion of renaming function results, it seems a plain bizarre language feature, and if it is different from making a constant and assigning the result of the function I find it doubly horrible. Still I suppose since this horrible feature is in the language it should work for language lawyers who are inclined to use it (for me I would ban it in coding standards except for renaming of enumeration literals -- it is a curious oddity of the language design that these are formally functions). **************************************************************** From: Tucker Taft Sent: Wednesday, November 9, 2011 6:03 PM For what it is worth, I use renaming of function results frequently for functions that return strings or records, and clearly for any functions that return limited types. It somehow makes me feel that less copying will take place. My model of what is happening is that when I initialize a constant with a copy of a function call, it will try to eliminate any junk on the (secondary) stack "above" the return object, sort of compacting the stack, sliding the result up the secondary stack. When I write "renames" I presume it will make no effort to "squeeze out" any junk on the secondary stack "above" the result object. I suspect that many compilers will treat them identically. But I would be curious whether typical users use an internal model similar to the one that I use, where they are seen as subtly distinct. Also, I wonder whether the *necessity* of using renames for limited types pre 2005, e.g. renaming the result of the Text_IO function Current_Output, might have a lingering affect on users, even as they move into 2005. **************************************************************** From: Steve Baird Sent: Wednesday, November 9, 2011 7:35 PM > I must say I hate the whole notion of renaming function results, it > seems a plain bizarre language feature, and if it is different from > making a constant and assigning the result of the function I find it > doubly horrible. It's not that I am so very fond of renaming function results; rather, I have a strong dislike for AI95-0167 and the special rules defined in that AI regarding assignment of invalid values. I would prefer to avoid relying on those rules. I believe (and this is just my opinion) that a rename of a function result better expresses my intent and, in that sense, improves program clarity. AI95-0167 allows certain ways of dealing with invalid U_C results. I'm not arguing against having those options available; I'm just saying that users should not be forced to use what I consider an inferior alternative if a better way is available. **************************************************************** From: Robert Dewar Sent: Wednesday, November 9, 2011 11:14 PM > AI95-0167 allows certain ways of dealing with invalid U_C results. > I'm not arguing against having those options available; I'm just > saying that users should not be forced to use what I consider an > inferior alternative if a better way is available. I agree this should be allowed (just not sure I agree it is a better way of doing things, seems a bit tricky and peculiar to me, and I cannot imagine a compiler where it makes a difference). **************************************************************** From: Jean-Pierre Rosen Sent: Thursday, November 10, 2011 6:57 AM > But I would be curious whether > typical users use an internal model similar to the one that I use, > where they are seen as subtly distinct. If you have a big enough user code base available, and want to do some statistics, the following AdaControl command might be of help: count declarations (function_call_renaming); **************************************************************** From: Robert Dewar Sent: Thursday, November 10, 2011 7:14 AM Does it exclude renaming of enumeration literals, this always seeems like a special case to me. **************************************************************** From: Jean-Pierre Rosen Sent: Thursday, November 10, 2011 8:50 AM FWIW, I just ran AdaControl on TACT (one of the big softwares from Eurocontrol). 3218 packages, 23 renamings of function calls. Considering that Eurocontrol is famous for using every possible construct of the language, it is not that much, but not 0 still. **************************************************************** From: Steve Baird Sent: Saturday, November 12, 2011 6:09 PM replace RM 13.9.1(12): A call to an imported function or an instance of Unchecked_Conversion is erroneous if the result is scalar, and the result object has an invalid representation, and the result is used other than as the expression of an assignment_statement or an object_declaration, or as the prefix of a Valid attribute. If such a result object is used as the source of an assignment, and the assigned value is an invalid representation for the target of the assignment, then any use of the target object prior to a further assignment to the target object, other than as the prefix of a Valid attribute reference, is erroneous. with A call to an imported function or an instance of Unchecked_Conversion is erroneous if the result is scalar, and the result object has an invalid representation, and the result is used other than as the expression of an assignment_statement or an object_declaration.[ as the name of an object_renaming-declaration, ] or as the prefix of a Valid attribute. If such a result object is used as the source of an assignment, and the assigned value is an invalid representation for the target of the assignment, then any use of the target object prior to a further assignment to the target object, other than as the prefix of a Valid attribute reference, is erroneous. ****************************************************************