!standard 6.5(22/2) 07-08-01 AI05-0058-1/01 !class binding interpretation 07-08-01 !status work item 07-08-01 !status received 07-05-10 !priority High !difficulty Easy !qualifier Error !subject !summary Only reaching the "end return" of an extended_return_statement causes the function to return to the caller. !question 6.5(22) reads: For the execution of an extended_return_statement, the handled_sequence_of_statements is executed. Within this handled_sequence_of_statements, the execution of a simple_return_statement that applies to the extended_return_statement causes a transfer of control that completes the extended_return_statement. Upon completion of a return statement that applies to a callable construct, a transfer of control is performed which completes the execution of the callable construct, and returns to the caller. The last sentence seems wrong. 7.6.1(2/2) defines completion as including reaching the end of a construct, leaving due to a transfer of control (such as an exit or goto), or by aborts or raising of exceptions. Surely we do not want an extended_return_statement to return to the caller when an exception propagates out of it. !recommendation (See Summary.) !wording Modify the last sentence of 6.5(22/2) as follows: ... Upon completion of a return statement that applies to a callable construct {by the normal completion of a simple_return_statement or by reaching the END RETURN of an extended_return_statement}, a transfer of control is performed which completes the execution of the callable construct, and returns to the caller. Add an AARM Note: Ramification: A transfer of control that completes an extended_return_statement (such as an exit or goto) does not cause a return to the caller unless it is a simple_return_statement (that is, triggers the second sentence of this paragraph). The return to the caller occurs for the simple_return_statement that applies to an extended_return_statement because the last sentence says "the normal completion of a simple_return_statement", which includes the one nested in the extended_return_statement. !discussion We can't just say "normal completion of a return statement", as that includes exits and gotos out of an extended_return_statement, and we surely don't want those to cause a return to the caller. !corrigendum 6.5(22/2) @drepl For the execution of an @fa, the @fa is executed. Within this @fa, the execution of a @fa that applies to the @fa causes a transfer of control that completes the @fa. Upon completion of a return statement that applies to a callable construct, a transfer of control is performed which completes the execution of the callable construct, and returns to the caller. @dby For the execution of an @fa, the @fa is executed. Within this @fa, the execution of a @fa that applies to the @fa causes a transfer of control that completes the @fa. Upon completion of a return statement that applies to a callable construct by the normal completion of a @fa or by reaching the @b of an @fa, a transfer of control is performed which completes the execution of the callable construct, and returns to the caller. !ACATS Test No separate ACATS test ought to be needed. !appendix !topic Possible errors in 6.5(22) !reference RM 6.5(22), 5.6, 5.7 !from Adam Beneschan 07-06-08 !discussion 6.5(22) reads: For the execution of an extended_return_statement, the handled_sequence_of_statments is executed. Within this handled_sequence_of_statements, the execution of a simple_return_statement that applies to the extended_return_statement causes a transfer of control that completes the extended_return_statement. Upon completion of a return statement that applies to a callable construct, a transfer of control is performed which completes the execution of the callable construct, and returns to the caller. (1) Is this accurate if the extended_return_statement is abandoned due to an exception? From what I can tell from 7.6.1, there are two kinds of completion---normal or abnormal---and an exception raised within an extended_return_statement (and not handled within the extended_return_statement) would cause abnormal completion of the statement. But it's still completion, and 6.5(22) would seem to imply that this causes execution to return to the caller---which of course is not the case. I'd suggest that the third sentence of 6.5(22) should probably begin "Upon normal completion..." (2) What happens if a goto or exit statement inside an extended_return_statement transfers control outside the extended_return_statement? (AARM 6.5(5.f) seems to think this is a possibility.) There's nothing in 5.6 or 5.7 that makes this illegal. Personally, I think it would be very strange to allow this. If you say you're going to return a result from the function, by starting an extended_return_statement, can you then change your mind and say that you're not going to return after all---by GOTOing or EXITing out of the extended_return_statement? (In particular, I think an "exit" that would leave an extended_return_statement is very likely to be a mistake.) My feeling is that 5.6 and 5.7 probably should be changed to treat extended_return_statements the same as accept_statements (you can't GOTO or EXIT out of an ACCEPT). Of course, allowing these statements inside extended_return_statements would not pose the same implementation issues that allowing them in an ACCEPT would, but I don't see a good reason why they should be allowed. (If this change is made, AARM 6.5(5.f) needs to be fixed also.) But if it's decided that GOTO and/or EXIT should be allowed to leave an extended_return_statement, then 6.5(22) will need to be changed, because in that case, we have a (normal) completion of a return statement that should *not* result in completion of the execution of the callable construct nor returning to the caller. **************************************************************** From: Randy Brukardt Sent: Friday, June 8, 2007 8:35 PM ... > (1) Is this accurate if the extended_return_statement is abandoned due > to an exception? From what I can tell from 7.6.1, there are two > kinds of completion---normal or abnormal---and an exception raised > within an extended_return_statement (and not handled within the > extended_return_statement) would cause abnormal completion of the > statement. But it's still completion, and 6.5(22) would seem to > imply that this causes execution to return to the caller---which > of course is not the case. I'd suggest that the third sentence of > 6.5(22) should probably begin "Upon normal completion..." You are correct; I don't think anyone ever read 7.6.1(2/2) in this context. Indeed, this paragraph is essentially garbage given the definition of "complete" given in 7.6.1(2/2). The only completion that is meant by this paragraph is "when the end of that execution has been reached" (to use the wording of 7.6.1(2/2)) and those defined by 6.5(22/2); all other forms of completion are not meant. I don't see any easy way to fix the wording to reflect that - the very tricky wording in 6.5(22/2) was intended to exclude other ways that return statement could be finished. The phase at the start of the third sentence was added so as to exclude simple returns nested in extended returns, and to clarify what actually was meant (it surely isn't clear in Ada 95 exactly what "Finally" applied to; one could read it as only applying to return-by-reference returns.) > (2) What happens if a goto or exit statement inside an > extended_return_statement transfers control outside the > extended_return_statement? (AARM 6.5(5.f) seems to think this is > a possibility.) There's nothing in 5.6 or 5.7 that makes this > illegal. Yes, it is intended that these work. Indeed, we reworded 9.3 in AI05-0045 because it failed to handle this case properly. > Personally, I think it would be very strange to allow this. If > you say you're going to return a result from the function, by > starting an extended_return_statement, can you then change your > mind and say that you're not going to return after all---by > GOTOing or EXITing out of the extended_return_statement? (In > particular, I think an "exit" that would leave an > extended_return_statement is very likely to be a mistake.) That's the so-called "black-hole" model, and we decided (after *much* discussion) that it is wrong for Ada. Even Ada 95 returns can be aborted and restarted with an exception, so the black-hole model would make extended returns behave very differently than simple returns. > My feeling is that 5.6 and 5.7 probably should be changed to treat > extended_return_statements the same as accept_statements (you > can't GOTO or EXIT out of an ACCEPT). Of course, allowing these > statements inside extended_return_statements would not pose the > same implementation issues that allowing them in an ACCEPT would, > but I don't see a good reason why they should be allowed. (If > this change is made, AARM 6.5(5.f) needs to be fixed also.) We discussed this extensively when the extended return was introduced, and we decided that the black-hole model doesn't make any sense, given that you have to be able to raise exceptions. (There are also use-cases for starting over with a return, particularly if you decide you need different bounds or discriminants.) The technical problem is that an extended return requires changing the master of an object in midstream; given that we can't ban exceptions from being raised, gotos are the least of the problems. (See the examples below). In any case, you are going about this backwards. You need a *good* reason to not allow something (in the absence of a clear technical problem), and "I can't think of a good reason why they should be allowed" doesn't work. Indeed, I think that I raised similar arguments at the time, and got a similar response. It's annoying to implement this, but life's tough. ;-) > But if it's decided that GOTO and/or EXIT should be allowed to > leave an extended_return_statement, then 6.5(22) will need to be > changed, because in that case, we have a (normal) completion of a > return statement that should *not* result in completion of the > execution of the callable construct nor returning to the caller. Yes, but not for this reason. The third sentence of 6.5(22/2) is not talking about "normal" completion (you are the one that decided that incorrectly), but *only* about reaching the end of the sequence of statements (or the equivalent transfer of control as described in the second sentence). It surely is not intended to apply to exceptions propagating, gotos out of, or anything else. Both: begin return A : Natural do A := Function_returning_minus_10; end return; exception when Constraint_Error => return 0; end; and begin return A : Natural do if Function_returning_minus_10 not in Natural then goto <> else A := Function_returning_minus_10; end if; end return; <> return 0; end; should work the same way. The net effect is that the wording of 6.5(22/2) is utter garbage for depending on the default meaning of "completion"; it'll have to be totally redone to avoid using that term at all. I can't think of any way to save it with a simple patch to the third sentence, because the second sentence also uses "completes" **************************************************************** From: Tucker Taft Sent: Sunday, June 10, 2007 7:03 AM > 6.5(22) reads: > > For the execution of an extended_return_statement, the > handled_sequence_of_statments is executed. Within this > handled_sequence_of_statements, the execution of a > simple_return_statement that applies to the extended_return_statement > causes a transfer of control that completes the > extended_return_statement. Upon completion of a return statement that > applies to a callable construct, a transfer of control is performed > which completes the execution of the callable construct, and returns > to the caller. The last sentence of the above paragraph probably needs to be reworded approximately as follows: ... Upon completion of a return statement that applies to a callable construct {by the normal completion of a simple_return_statement or by reaching the END RETURN of an extended_return_statement}, a transfer of control is performed which completes the execution of the callable construct, and returns to the caller. **************************************************************** From: Randy Brukardt Sent: Sunday, June 10, 2007 9:37 PM I don't think that works, because (1) it puts the critical information into parens; you want to talk about only certain completions, but nothing in the sentence says that. One can read the stuff in parens as informative rather than an exclusive list of what completions are meant; (2) Presuming you did mean it be exclusive, it doesn't take into account completions of an extended return by the execution of a nested simple return. I think you have to avoid the term completion altogether, or define a new term like "ordinary completion" in 7.6.1 and then use that here (in both the second and third sentences). Not a simple fix... **************************************************************** From: Tucker Taft Sent: Monday, June 11, 2007 7:43 AM > I don't think that works, because > (1) it puts the critical information into parens; you want to talk about > only certain completions, but nothing in the sentence says that. One can > read the stuff in parens as informative rather than an exclusive list of > what completions are meant; Those aren't parentheses, they are the usual braces we use to indicate an insertion. Better get a new prescription for your glasses... ;-) > (2) Presuming you did mean it be exclusive, it doesn't take into account > completions of an extended return by the execution of a nested simple > return. I don't agree, since it talks about the normal completion of a simple_return_statement, which includes the case of a nested simple_return_statement. (Note that it says *a* simple_return_statement rather than *the* simple_return_statement.) ****************************************************************