To: J3 J3/19-173r1 From: Van Snyder Subject: Rank-agnostic allocation and pointer assignment Date: 2019-August-08 References: 18-247 19-110r1 19-150 Sections of 19-173 other than 2.1 and 2.2 have been removed. Section 2.4 to cover the case of specifying pointer lower bounds has been added. 2.2 Deferred shape object allocation .................................... Allow to allocate a deferred-shape object using a rank-one object of explicit shape and constant extent to specify bounds, e.g. allocate ( Y ( A ) ) ! lbound(Y) == [1,1,...], ubound(Y) == A, ! SIZE(A,1) is a constant expression or, more generally allocate ( Y ( B : A ) ) ! lbound(Y) == B, ubound(Y) == A, SIZE(A,1) ! == SIZE(B,1) are constant expressions e.g., allocate ( Y ( lbound(A)-1 : ubound(A) + 1 ) insead of requiring allocate ( Y(lbound(a,1)-1:ubound(a,1)+1, & & lbound(a,2)-1:ubound(a,2)+1, & & lbound(a,3)-1:ubound(a,3)+1) ) The latter is not useful in a generic-programming context, wherein RANK(Y) depends upon a generic parameter. One bound could be a scalar, which is "broadcast" to the same shape as the other bound, e.g. allocate ( Y ( 0 : shape(A)+1 ) ) instead of requiring allocate ( Y ( [ ( 0, i = 1, rank(A) ) ] : shape(A)+1 ) ) If the object (Y in the examples) is (allowed to be) a scalar, the object used to declare the bounds (A in the examples) shall be an array, and its extent shall be zero. The Y@(A) notation is not necessary to distinguish from vector subscripting because a vector subscript cannot be used to specify the bounds of an object during allocation. SIZE(A,1) might be zero, in which case Y shall be a scalar. 2.3 Pointer rank remapping .......................... In a rank-remapping pointer assignment, the bounds of a pointer object can be specified by rank-one arrays whose extents are constant constant expressions that have the same value: P(A:B) => M(...) or more generally: P( lbound(A)-1 : ubound(A)+1 ) => M(...) instead of requiring P( lbound(A,1)-1 : ubound(A,1)+1, & & lbound(A,2)-1 : ubound(A,2)+1, & & lbound(A,3)-1 : ubound(A,3)+1 ) => M(...) The latter is not useful in a generic-programming context, wherein SIZE(A,1) depends upon a generic parameter. In all cases, the rank of P is the extent of the bounds. One set of bounds could be specified by a scalar, which is "broadcast" to the same extent as the other bound, which specifies the rank, e.g. P ( 0 : shape(A)+1 ) => M(...) instead of requiring P ( [ ( 0, i = 1, rank(A) ) ] : shape(A)+1 ) => M(...) The P@(A) notation is not necessary to distinguish from vector subscripting because a vector subscript cannot be used to specify the bounds during rank-remapping pointer assignment. SIZE(A,1) might be zero, in which case P shall be a scalar pointer. 2.4 Pointer lower bounds ------------------------ This subclause was not part of 19-173. Allow to specify the lower bounds of a pointer during pointer assignment using a single rank-one array with constant extent: P(A:) => M(...) wherein the extent of A shall be the same as the rank of P, instead of requiring P(A(1):,A(2):,A(3):) => M(...) which is not useful in a generic-programming context, wherein RANK(P) depends upon a generic parameter. The P@(A) notation is not necessary to distinguish from vector subscripting because a vector subscript cannot be used to specify the lower bounds during pointer assignment. SIZE(A,1) might be zero, in which case P shall be a scalar pointer.