!standard 06.04.01 (13) 99-05-27 AI95-00110/04 !class confirmation 96-04-04 !status WG9 approved 96-12-07 !status ARG approved 12-0-0 96-10-07 !status ARG approved 7-0-1 (subject to editorial review) 96-06-17 !status work item 96-04-04 !status received 96-04-04 !priority Medium !difficulty Medium !subject No Constraint Check on 'out' Parameter of an Access Type !summary For a parameter of mode 'out', of an access type, there is no constraint check before the call. !question AARM-6.4.1 says: 12 For an out parameter that is passed by copy, the formal parameter object is created, and: 13 For an access type, the formal parameter is initialized from the value of the actual, without a constraint check; 13.a Reason: This preserves the Language Design Principle that an object of an access type is always initialized with a ``reasonable'' value. Noting that out parameters are readable in Ada 95, consider the following example: type Pointer is access String; P: Pointer := new String'("hello"); subtype Pointer_10 is Pointer(1 .. 10); procedure Proc(Param: out Pointer_10) is begin -- What is Param'Length here? ... Param := new String'("0123456789"); -- 10 characters, here. end Proc; ... Proc(P); Given the current rules, the only reasonable value for Param'Length is 5. !response For a parameter of mode 'out', of an access type, there is no constraint check before the call. This implies that inside the procedure, the bounds or discriminants of the parameter might not obey the constraint of its type. Param'Length is indeed 5 in the above example. This rule is necessary for upward compatibility; the above program did not raise Constraint_Error in Ada 83, so we want to keep it that way. Note that this is no more harmful than the fact that a scalar 'out' parameter can have an "uninitialized" value upon entry to a procedure, and the uninitialized value does not necessarily obey the constraint. !ACATS test ACATS test C64103F.ADA tests that an 'out' parameter of an access type does not raise Constraint_Error. !appendix !section 6.4.1(12) !subject No constraint check on out parameter of an access type? !reference AARM95-6.4.1(12,13,13.a) !reference AARM95-6.2(13.a) !from Keith Thompson 95-11-01 !reference 95-5377.a Keith Thompson 95-11-1>> !discussion In 6.4.1, we read the following: > 12 For an out parameter that is passed by copy, the formal parameter > object is created, and: > > 13 For an access type, the formal parameter is initialized > from the value of the actual, without a constraint check; > > 13.a Reason: This preserves the Language Design Principle that an > object of an access type is always initialized with a > ``reasonable'' value. Noting that out parameters are readable in Ada 95, what should be the output of the following program? with Ada.Text_IO; use Ada.Text_IO; procedure Foo is type Pointer is access String; P: Pointer := new String'("hello"); subtype Pointer_10 is Pointer(1 .. 10); procedure Proc(Param: out Pointer_10) is begin Put_Line("Param'Length = " & Integer'Image(Param'Length)); end Proc; begin Proc(P); end Foo; Given the current rules, the only reasonable value for Param'Length is 5, but it shouldn't be this easy to create an object whose value doesn't satisfy its declared subtype. This would also contradict the statement of AARM95-6.2(13.a) that "An out parameter is treated like a declared variable without an explicit initial expression.", though it's probably ok for that statement not to apply to access type parameters. I suggest that a constraint check is needed, and that the call should raise Constraint_Error. **************************************************************** !section 6.4.1(12) !subject No constraint check on out parameter of an access type? !reference AARM95-6.4.1(12,13,13.a) !reference AARM95-6.2(13.a) !reference 95-5377.a Keith Thompson 95-11-01 !from Tucker Taft 95-11-02 !reference 95-5378.a Tucker Taft 95-11-2>> !discussion > In 6.4.1, we read the following: > > > 12 For an out parameter that is passed by copy, the formal parameter > > object is created, and: > > > > 13 For an access type, the formal parameter is initialized > > from the value of the actual, without a constraint check; > > > > 13.a Reason: This preserves the Language Design Principle that an > > object of an access type is always initialized with a > > ``reasonable'' value. > > Noting that out parameters are readable in Ada 95, what should be the > output of the following program? > > with Ada.Text_IO; use Ada.Text_IO; > procedure Foo is > type Pointer is access String; > P: Pointer := new String'("hello"); > subtype Pointer_10 is Pointer(1 .. 10); > > procedure Proc(Param: out Pointer_10) is > begin > Put_Line("Param'Length = " & Integer'Image(Param'Length)); > end Proc; > > begin > Proc(P); > end Foo; > > Given the current rules, the only reasonable value for Param'Length is > 5, but it shouldn't be this easy to create an object whose value doesn't > satisfy its declared subtype. This would also contradict the statement > of AARM95-6.2(13.a) that "An out parameter is treated like a declared > variable without an explicit initial expression.", though it's probably > ok for that statement not to apply to access type parameters. > > I suggest that a constraint check is needed, and that the call should > raise Constraint_Error. This would create an incompatibility with Ada 83, in that there is no incoming constraint check in Ada 83 on OUT parameters of an access type. In general in Ada 95, a compiler needs to recognize the notion of an object having an "unreliable" subtype. This is the case with an uninitialized scalar variable -- the compiler can't necessarily believe the declared subtype, though it must still check against it on any assignment to the variable. For an OUT parameter of a constrained access subtype, the compiler cannot believe the declared subtype, until it knows the OUT parameter has been assigned to inside the subprogram. Having OUT parameters of an access type outside of their declared subtype seems not particularly different from having OUT parameters of a scalar type outside of their declared subtype. It certainly doesn't seem serious enough to introduce an incompatibility with Ada 83 in this area. -Tuck ****************************************************************