!standard 6.1(30/3) 20-12-15 AI12-0408-1/04 !standard 6.7(3/3) !standard 6.7(4/2) !standard 6.8(3.1/5) !standard 6.8(7/4) !class binding interpretation 20-12-02 !status Amendment 1-2012 20-12-11 !status ARG Approved 15-0-0 20-12-09 !status work item 20-12-02 !status received 20-10-27 !priority Low !difficulty Easy !qualifier Clarification !subject Definition of "null procedure" and "expression function" !summary We clarify the definition of the term "null procedure" so that it applies only to procedures whose *declaration* is a null_procedure_declaration. A similar clarification is applied to the term "expression function". !question Is a procedure that has a "normal" declaration but is completed with a null_procedure_declaration considered a "null procedure"? (No.) !response The definition of "null procedure" is a bit ambiguous now that a null procedure declaration can be used as a completion. 6.1(30/3) (marked redundant) says that a subprogram DECLARED by a null_procedure_declaration is a null procedure, while a subprogram declared by a normal subprogram_declaration is not. 6.7(3/3) says that "a null_procedure_declaration declares a null procedure" as well as allowing it to complete another subprogram. A completion never declares anything, so it is clear from these rules that a completion is not a null procedure. But it probably isn't clear to a casual reader. Moreover, since a completion is not a null procedure, we don't have any definition of the execution of a null_procedure_declaration that is a completion. !wording Modify 6.7(3/3): A null_procedure_declaration {that is not a completion} declares a /null procedure/. A completion is not allowed for a null_procedure_declaration; however, a null_procedure_declaration can complete a previous declaration. Modify 6.7(4/2): The execution of a null procedure is invoked by a subprogram call. For the execution of a subprogram call on a null procedure{, or on a procedure completed with a null_procedure_declaration}, the execution of the subprogram_body has no effect. Modify 6.8(3.1/5): An expression_function_declaration {that is not a completion} declares an /expression function/. The /return expression of an expression function/ is the expression or aggregate of the expression_function_declaration. A completion is not allowed for an expression_function_declaration; however, an expression_function_declaration can complete a previous declaration. [Editor's note: The term is "return expression of an expression function", not two separate terms as it was in the Ada 2012 corrigendum. Note that this paragraph was moved up in Ada 202x, but it has existed from the initial definition of expression functions.] Modify 6.8(7/4): The execution of an expression function is invoked by a subprogram call. For the execution of a subprogram call on an expression function{, or on a function completed with a expression_function_declaration}, the execution of the subprogram_body executes an implicit function body containing only a simple_return_statement whose expression is the return expression [that] of the expression function. !discussion Whether or not a procedure is a "null procedure" is relevant to certain legality rules. In particular, when specifying certain aspects on a procedure declaration, the legality may depend on whether the procedure is a null procedure. Clearly, such a legality rule cannot depend on how the procedure is completed, since the completion might well be in a separate compilation unit. When a procedure is completed with a null_procedure_declaration, it should be indistinguishable from a procedure completed with a body of "... is begin null; end;". If No_Return is specified on the declaration of such a procedure, one should expect Program_Error to be propagated if the procedure is invoked. Clearly the compiler could give a warning if it compiles a null_procedure_declaration as the body for such a procedure, just as it could warn if the procedure has a body of "... is begin null; end;". Similar issues arise whether or not a function is an "expression function". The term "return expression" of an expression function is intended to apply to all expression_function_declarations (since it is about rules inside of an expression function, not external uses). We keep the term, but make the entire phrase the term. As this term phrase is used in a number of rules scattered throughout the Standard, changing it is not appealing. !corrigendum 6.7(3/3) @drepl A @fa declares a @i. A completion is not allowed for a @fa; however, a @fa can complete a previous declaration. @dby A @fa that is not a completion declares a @i. A completion is not allowed for a @fa; however, a @fa can complete a previous declaration. !corrigendum 6.7(4/2) @drepl The execution of a null procedure is invoked by a subprogram call. For the execution of a subprogram call on a null procedure, the execution of the @fa has no effect. @dby The execution of a null procedure is invoked by a subprogram call. For the execution of a subprogram call on a null procedure, or on a procedure completed with a @fa, the execution of the @fa has no effect. !corrigendum 6.8(3/4) @dinsa The expected type for the @fa or @fa of an @fa is the result type (see 6.5) of the function. @dinss @s8<@i> An @fa that is not a completion declares an @i. The @i is the @fa or @fa of the @fa. A completion is not allowed for an @fa; however, an @fa can complete a previous declaration. !corrigendum 6.8(7/4) @drepl The execution of an expression function is invoked by a subprogram call. For the execution of a subprogram call on an expression function, the execution of the @fa executes an implicit function body containing only a @fa whose @fa is the return expression of the expression function. @dby The execution of an expression function is invoked by a subprogram call. For the execution of a subprogram call on an expression function, or on a function completed with a @fa, the execution of the @fa executes an implicit function body containing only a @fa whose @fa is the return expression of the expression function. !ASIS No ASIS effect. !ACATS test One could create an ACATS test to check the cases mentioned in the discussion, but those are unlikely in practice (and the No_Return one represents a program bug). !appendix From: Tucker Taft Sent: Tuesday, October 27, 2020 2:47 PM The definition of "null procedure" is a bit ambiguous now that a null procedure declaration can be used as a completion. This tripped up one of our engineers. A procedure is *not* a null procedure unless its *declaration* is a null_procedure_declaration. If its *completion* is a null_procedure_declaration, then from the language rules point of view it is *not* a "null procedure," e.g. with respect to the rule that the No_Return aspect cannot be specified True for a null procedure. Hence, I would suggest we tweak the wording in 6.7(3/3): A null_procedure_declaration {that is not a completion} declares a /null procedure/. A completion is not allowed for a null_procedure_declaration; however, a null_procedure_declaration can complete a previous declaration. **************************************************************** From: Steve Baird Sent: Tuesday, October 27, 2020 2:56 PM I agree that this would be a useful clarification. **************************************************************** Editor's note: Tucker had noticed that the use of the term "null procedure" in the dynamic semantics was incorrect. I noticed that "expression function" has a similar definition (especially in 6.1), and thus needs a similar fix. Version /02 of the AI reflects all of the needed fixes. ****************************************************************