ISO/IEC JTC1/SC22/WG5 N1805 Fortran interpretations that have passed a J3 letter ballot Stan Whitlock There are 28 Fortran 2003 interps in 09-006Ar4 plus the results of LB #20 in 10-105 that have passed a J3 letter ballot and are ready for WG5 approval. ********************************************************************** * B E F95/0098 Are dummy functions returning assumed-length character legal? * B E F03/0022 Coexistence of IEEE and non-IEEE kinds * B E F03/0024 DEALLOCATE and array pointers * B E F03/0034 IEEE_LOGB() * B E F03/0039 HYPOT() * B E F03/0063 Procedure pointers in BLOCK DATA program units * B E F03/0071 Subroutine/function ambiguity in generics * B C F03/0078 IEEE_SUPPORT_DATATYPE vs. mathematical equivalence * B E F03/0090 Polymorphic array constructors * B E F03/0112 Attributes allowed for dummy arguments in defined assignments * B E F03/0119 Elemental procedures and deferred length character components * B E F03/0122 When do objects of sequence derived type have the same type? * B E F03/0125 Definitions of EXTENDS_TYPE_OF and SAME_TYPE_AS * B E F03/0126 References to VOLATILE variables in pure procedures * B E F03/0127 Duration of procedure execution * B E F03/0129 C_LOC of character substrings * B I F03/0130 Elemental specific intrinsic procedure characteristics * B E F03/0131 SAVE attribute and EQUIVALENCE * B E F03/0132 Unformatted i/o and private components * B E F03/0133 Is unlimited polymorphic allowed in COMMON? * B E F03/0134 Implicit typing of procedure pointers * B E F03/0135 Interaction between RESULT, recursion, and host generic * B E F03/0136 Are subroutines distinguishable from arrays? * B E F03/0137 Dummy procedure type compatibility * B E F03/0138 External as * B E F03/0139 Functions returning procedure pointers * B E F03/0140 Type of nested construct entities * B E F03/0141 More than one specific interface for a procedure ---------------------------------------------------------------------- NUMBER: F95/0098 TITLE: Are dummy functions returning assumed-length character legal? KEYWORDS: Dummy function, assumed-length character DEFECT TYPE: Erratum STATUS: Passed by J3 letter ballot QUESTION: (1) Is a dummy function allowed to have assumed character length? (2) If so, can it be invoked directly from that scoping unit? (3) If so, is this still true if the invoked function itself has a result variable that is assumed-length (this is obsolescent). (4) If an assumed-length function is declared in another scoping unit as a specific length, can it be passed as an actual argument that corresponds to a dummy function of that specific length and be invoked via the dummy function? (5) Clarification request - see discussion - Example 1 does not have any external function with assumed character length, so does it use any obsolescent feature or not? Example 1 (for questions 1 and 2): PROGRAM EX1 CHARACTER F*5 EXTERNAL F CALL S(F) END SUBROUTINE S(D) CHARACTER D*(*) PRINT *,D() END CHARACTER*5 FUNCTION F() F = 'OK' END Example 2 (for question 3): The same as example 1 except for F which is assumed-length, making the whole example 2: PROGRAM EX2 CHARACTER F*5 EXTERNAL F CALL S(F) END SUBROUTINE S(D) CHARACTER D*(*) PRINT *,D() END CHARACTER*(*) FUNCTION F() F = 'OK' END Example 3 (for question 4): The same as example 3 except that S declares the dummy function with a specific length, making it: PROGRAM EX3 CHARACTER F*5 EXTERNAL F CALL S(F) END SUBROUTINE S(D) CHARACTER D*5 PRINT *,D() END CHARACTER*(*) FUNCTON F() F = 'OK' END DISCUSSION: Examples 2 and 3 use the obsolescent feature of "assumed length character for an external function". It seems ambiguous whether example 1 uses an obsolescent feature: by C416 and the text of 4.4.4.1 it would apparently not be obsolescent but by C417 it would appear to be obsolescent. Example 1 does not use any feature described in Annex B, which implies that it is not obsolescent. It would be nice to clarify this. A straightforward reading of the literal words of the standard appears to indicate that example 1 is standard-conforming, but that example 2 is not valid due to it violating item 4 of the list at the end of subclause 4.4.4.1 (page 41). Similarly, example 3 would appear to be invalid by the same rule: this last certainly seems counter-intuitive, but does seem to be what the standard literally says. The basic issue underlying examples 1 and 2 is that the standard says "If used to declare a dummy argument of a procedure, the dummy argument assumes the length of the associated actual argument." It has been argued that this should only apply to dummy variables and not to dummy functions, but that is not what the standard says. ANSWER: (1) Yes, a dummy function is allowed to have assumed length; this is clearly implied by the permission given in C417. (2) Yes, there is no prohibition against invoking such a function. (3) Yes, the actual invoked function may have an assumed-length result. The prohibition against this in item (4) is an error; an edit is supplied to correct this. (4) Yes, this is also valid. The prohibition against this in item (4) is in error; an edit is supplied to correct this. (5) The implication of constraint C417 that a dummy function having assumed length is obsolescent is a typographical error: an edit is provided to correct this. EDITS: [41:11-12] In C417, change "\obs{unless ... dummy function}" to "unless it is of type CHARACTER and is the name of a dummy function \obs{or the name of the result of an external function}". {Note: \obs{...} indicates obsolescent font.} [41:34,36] At the end of 4.4.4.1, item (4), after "invoking the function" insert ", or passing it as an actual argument"; change "host or use" to "argument, host, or use". SUBMITTED BY: Larry Meadows HISTORY: 02-157 m160 F95/0098 submitted 04-417r1 m170 Duplicate of interp #6 05-180 m172 Failed WG5 ballot N1617 - not a duplicate of F95 interp 000006 09-233 m188 Revised answer 09-261 m189 Revised again 09-263 m189 Rewritten and revised to cover more of the issue - Passed by J3 meeting 09-295 m190 Passed by J3 letter ballot #19 09-292 ---------------------------------------------------------------------- NUMBER: F03/0022 TITLE: Coexistence of IEEE and non-IEEE kinds KEYWORDS: IEEE, kind DEFECT TYPE: Erratum STATUS: Passed by J3 letter ballot QUESTION: Is it allowed for a processor to have one or more real kinds for which there is no IEEE support, while also having real kinds for which there is IEEE support? Much of the IEEE material appears to assume that a processor could simultaneously support both IEEE and non-IEEE kinds. I thought this was the intent. However, the first sentence of the second paragraph in section 14 says that if IEEE_EXCEPTIONS or IEEE_ARITHMETIC is accessible in a scoping unit, then IEEE_OVERFLOW and IEEE_DIVIDE_BY_ZERO are supported in the scoping unit for *ALL* [emphasis mine] kinds of real and complex data. This says to me that if there is any kind of real for which the processor cannot support IEEE_OVERFLOW or IEEE_DIVIDE_BY_ZERO, then pretty much none of the IEEE stuff can be used on that processor at all; there isn't much of the IEEE stuff that can be used without IEEE_ARITHMETIC or IEEE_EXCEPTIONS. This seems draconian and unintended. I speculate that this condition is intended to apply to all IEEE real kinds rather than to all real kinds. ANSWER: Yes, this is allowed. It was a mistake to require that IEEE_OVERFLOW and IEEE_DIVIDE_BY_ZERO be supported for all kinds of real and complex data within that scoping unit. Support of these two flags means that the exceptions can be detected for real and complex kinds that are IEEE floating point data. The Standard makes no claims about non-IEEE kinds. An edit is provided to clarify this. EDITS: All edits pertain to 04-007. Clause 14 "Exceptions and IEEE arithmetic", 1st sentence of 2nd paragraph [363:9-10] replace "for all kinds of real and complex data" with "for all kinds of real and complex IEEE floating-point data" SUBMITTED BY: Richard Maine HISTORY: 04-419 m170 F03/0022 submitted 04-419r1 m170 Passed by J3 meeting 05-146 m171 Failed J3 letter ballot #10 09-223 m188 Revised answer 09-223r1 m188 Passed by J3 meeting + F2008 fix 09-226 09-295 m190 Passed as amended by J3 letter ballot #19 09-292 ---------------------------------------------------------------------- NUMBER: F03/0024 TITLE: Pointer deallocation and "whole object" KEYWORDS: DEALLOCATE, POINTER DEFECT TYPE: Erratum STATUS: Passed by J3 letter ballot QUESTION: 6.3.3.2 paragraph 2 (F03 [116:24-25]) states "If a pointer appears in a DEALLOCATE statement, it shall be associated with the whole of an object that was created by allocation." What does this requirement entail? In particular, which of the following examples conform to this requirement? Q1. REAL,POINTER :: X(:),Y(:) ALLOCATE(X(10)) Y => X(1:10) ! Note that ASSOCIATED(X,Y) is true. DEALLOCATE(Y) Q2. REAL,POINTER :: X(:),Y(:) ALLOCATE(X(10)) Y => X(10:1:-1) ! Note that ASSOCIATED(X,Y) is false because the order differs. DEALLOCATE(Y) Q3. REAL,POINTER :: X(:),Y(:) ALLOCATE(X(0)) Y => X ! Note that ASSOCIATED(X,Y) is false because they are zero-sized. DEALLOCATE(Y) Q4. REAL,POINTER :: X(:),Y(:,:) ALLOCATE(X(100)) Y(1:10,1:10) => X(1:100) ! Note that ASSOCIATED(X,Y) is false because the shapes differ. DEALLOCATE(Y) Q5. REAL,POINTER :: X(:),Y ALLOCATE(X(1)) Y => X(1) ! Note that one is not permitted to ask ASSOCIATED(X,Y). DEALLOCATE(Y) Q6. TYPE T REAL NOTHING(0) REAL A(0) CHARACTER C END TYPE TYPE(T),POINTER :: X CHARACTER,POINTER :: Y ALLOCATE(X) Y => X%C ! Note that one is not permitted to ask ASSOCIATED(X,Y). DEALLOCATE(Y) Q7. TYPE T CHARACTER C END TYPE TYPE,EXTENDS(T) :: XT ! No additional components END TYPE TYPE(XT),POINTER :: X TYPE(T),POINTER :: Y ALLOCATE(X) Y => X%T ! Note that one is not permitted to ask ASSOCIATED(X,Y). DEALLOCATE(Y) ANSWER: In this context, "whole object" requires the type and type parameter values to be the same, and if the object is an array that the elements are the same elements in the same array element order. A scalar is never the "whole" of an array (a processor is permitted to have extra padding between array elements). This gives the answers to the specific questions as follows: Q1 - conforming; Q2 - not conforming (order differs); Q3 - conforming; Q4 - conforming; Q5 - not conforming (scalar vs. array); Q6 - not conforming (type differs); Q7 - not conforming (type differs). An edit is supplied to clarify this intent. EDITS: [116:25] After "by allocation." insert new sentence "The pointer shall have the same dynamic type and type parameters as the allocated object, and if the allocated object is an array the pointer shall be an array whose elements are the same as those of the allocated object in array element order." SUBMITTED BY: Aleksandar Donev HISTORY: 04-378 m170 F03/0024 submitted 04-378r1 m170 Passed by J3 meeting 05-146 m171 Failed J3 letter ballot #10 09-205 m188 Revised answer - passed by J3 meeting + F2008 fix 09-226 09-295 m190 Passed by J3 letter ballot #19 09-292 ---------------------------------------------------------------------- NUMBER: F03/0034 TITLE: IEEE_LOGB() KEYWORDS: IEEE-754, ieee_logb() DEFECT TYPE: Erratum STATUS: Passed by J3 letter ballot QUESTION: What is ieee_logb(denormal)? Is it of the hardware representation, or is it as if the hardware had an unbounded exponent range? What is ieee_logb(NaN)? ieee_logb(-INF)? ieee_logb(+INF)? ieee_logb() should be defined as if the hardware representation had an unbounded exponent range. ieee_logb(NaN) should be the same NaN; shall be a NaN. ieee_logb(-INF) shall be +INF ieee_logb(+INF) shall be +INF ANSWER: Case (i) of 14.10.12 correctly specifies that if the value of X is denormal, its unbiased exponent is returned, that IEEE_LOGB(X) is equal to EXPONENT(X)-1. That this conclusion is true is the subject of F2003 interp F03/0054, answered in Corrigendum 1. For consistency with the IEEE International Standard, edits are also supplied for the case where X is infinite and X is NaN. EDITS: Page and line numbers refer to 04-007. Subclause 14.10.12 "IEEE_LOGB (X)" Result value [376:17+] add: "Case (iii) If IEEE_SUPPORT_INF(X) is true and X is infinite, the result is +infinity. Case (iv) If IEEE_SUPPORT_NAN(X) is true and X is a NaN, the result is a NaN." SUBMITTED BY: Fred Tydeman HISTORY: 05-113 m171 F03/0034 submitted 05-113r1 m171 Passed by J3 meeting 05-170 m172 Passed J3 letter ballot #11 N1622 m172 Failed WG5 ballot N1629 09-221 m188 Revised answer 09-221r1 m188 Passed by J3 meeting + F2008 fix 09-226 09-295 m190 Passed by J3 letter ballot #19 09-292 ---------------------------------------------------------------------- NUMBER: F03/0039 TITLE: HYPOT() KEYWORDS: IEEE-754, hypot() DEFECT TYPE: Erratum STATUS: Passed by J3 letter ballot QUESTION: HYPOT is the Fortran function defined in Note 14.17. What is HYPOT(NaN,infinity)? HYPOT(NaN,finite)? HYPOT(X,Y) when X and/or Y is an infinity (even if the other is a NaN) shall be +infinity. Reason: hypot(), when one of the arguments is an infinity, is +infinity independent of the value of the other argument. So, if the NaN argument is replaced by zero, any finite number, or any infinity, hypot(infinity,NaN) is still infinity. HYPOT(X,Y) when X and/or Y is a NaN (and neither is infinite) shall be a NaN, and should one of the NaN arguments. ANSWER: The HYPOT example in note 14.17 illustrates the use of the features of this section to provide reliable software that is fast in the uncomplicated case. We did not consider what would happen if one of the arguments is a NaN and have therefore edited the text. DISCUSSION: In fact, if either X or Y is a NaN, the first executable statement will set HYPOT to a NaN without signaling an exception. The slower code in the IF construct will therefore not be executed and a NaN will be returned, which is consistent with the way NaNs are handled by intrinsic operators, see paragraph 3 of section 6.2 of the IEEE International Standard. To make this explicit, an edit is provided to test for these conditions. EDITS: Page and line numbers refer to 04-007. [page 389]. Subclause 14.11, Note 14.17, after the comment "! The processor clears the flags on entry" insert " IF (IEEE_IS_NAN (X) .OR. IEEE_IS_NAN (Y)) THEN HYPOT = SQRT (-1.0) RETURN ENDIF" [page 389]. Subclause 14.11, Note 14.17, final paragraph, line 2. Before "exception" add "overflow or underflow". SUBMITTED BY: Fred Tydeman HISTORY: 05-118 m171 F03/0039 submitted 05-118r3 m171 Passed by J3 meeting 05-170 m172 Passed J3 letter ballot #11 N1622 m172 Failed WG5 ballot N1629 09-222 m188 Revised answer 09-222r1 m188 Revised again to test for NAN arguments 09-222r2 m188 Passed by J3 meeting + F2008 fix 09-226 09-295 m190 Passed by J3 letter ballot #19 09-292 ---------------------------------------------------------------------- NUMBER: F03/0063 TITLE: Procedure pointers in BLOCK DATA program units KEYWORDS: Procedure pointer, common block, block data DEFECT TYPE: Erratum STATUS: Passed by J3 letter ballot QUESTION: It is clear that procedure pointers are permitted in common blocks. However, due to the restrictions on BLOCK DATA program units, it seems that such a common block can not appear in a BLOCK DATA program unit. Was it intended that common blocks containing procedure pointers could be initialized in a BLOCK DATA program unit? ANSWER: It was a mistake to try to allow procedure pointers in common blocks. Edits are provided to correct this blunder. EDITS: All edits refer to 04-007. [98:17] Delete the second line of R558 {114:19 R569 in 09-007r1}. [98:18] Remove "or " {114:21 in 09-007r1}. [98:21] After "allocatable" insert "a procedure pointer," {114:24 in 09-007r1}. [98:25] Remove "or " {115:2 in 09-007r1}. [411:21] Remove item (7) in the list of names in a scoping unit that override the same host-associated name. {448:22 in 09-007r1}. SUBMITTED BY: Rob James HISTORY: 05-178 m172 F03/0063 submitted 05-225 m173 Passed by J3 meeting 06-133r2 m175 Passed J3 letter ballot #12 N1658 m176 Failed WG5 ballot N1657 09-148 m187 Revised answer, passed by J3 meeting 09-187r2 m188 Passed J3 letter ballot #18 09-155 as modified F2008 note: include edits above + [04-007/98:21-22 5.5.2 C588] Delete "a function name, an entry name," because these were originally synonyms for "a result name" (as applied to in R558). Now, "a function name" (as applied to in R558) prohibits function pointers. ---------------------------------------------------------------------- NUMBER: F03/0071 TITLE: Subroutine/function ambiguity in generics KEYWORDS: subroutine, generic, implicit DEFECT TYPE: Erratum STATUS: Passed by J3 letter ballot QUESTION: Q1. Is the following generic allowed? interface q subroutine qr(f) implicit real(f) external f end subroutine subroutine qc(f) implicit complex(f) external f end subroutine end interface q The uncertainty arises because it is not established whether F is a subroutine or a function. If either F were a subroutine, then it would be clear that the generic was disallowed. One might be able to use this to deduce that both Fs must be functions. This seems like an obscure deduction to demand of the compiler. Q2. Consider the following "obviously" allowed generic module m interface q subroutine qr(f) real, external :: f end subroutine subroutine qc(f) complex, external :: f end subroutine end interface q end module m Is the following main program valid? program main use m external ff call q(ff) end Again, the problem is that it is unclear whether or not ff is a function or subroutine. If it is a subroutine, then the call is ambiguous. One might thus deduce that ff must be a function, and therefore of type real, but this seems like an obscure deduction to demand of the compiler. ANSWER: 1. The program fragment is not conforming. A generic interface is required to be nonambiguous. This is a similar situation to the declaration of an external procedure in a module, where a procedure that is a function is required to have its type and type parameters explicitly declared. An edit is provided to require this for specific procedures in a generic interface. 2. The main program program unit is conforming, although the program would not be if the external procedure FF were not in fact a real function. If the reference had been to QR instead of Q, it would be clear that FF has to be a real function, from the point of view of the main program scoping unit. At the call site, the reference to Q is known to be a reference either to QR or QC (the interface block for Q is not defective), both of which require a function actual argument. FF is known to be either a subroutine or a function, since it explicitly has the EXTERNAL attribute, and if it is a function it is known by implicit typing rules to be real. Because neither specific in the generic allows a subroutine as an argument, FF must therefore be a function. Since FF is real, QR is called. (The generic cannot have a specific that accepts a subroutine as an argument, as that would violate the requirements in 16.2.3.) EDITS: [261:3] In 12.3.2.1 Interface block, immediately after "A generic interface is always explicit.", append new sentence to paragraph "If a specific procedure in a generic interface has a function dummy argument, that argument shall have its type and type parameters explicitly declared in the specific interface." {I.e. if you just say EXTERNAL dummy, you must mean a subroutine.} SUBMITTED BY: Richard Maine HISTORY: 05-265 m174 F03/0071 submitted 08-189r1 m184 Answer provided - Passed by J3 meeting 08-259 m185 Failed J3 letter ballot #17 08-213 08-262 m185 Passed by J3 meeting 09-187r2 m188 Passed J3 letter ballot #18 09-155 F2008 note: edit is 09-007r1 [285:5+] 12.4.3.4.1 "Generic identifiers" after "A generic interface is always explicit." - edit not passed as of m188 ---------------------------------------------------------------------- NUMBER: F03/0078 TITLE: IEEE_SUPPORT_DATATYPE vs. mathematical equivalence KEYWORDS: IEEE_SUPPORT_DATATYPE, mathematical equivalence DEFECT TYPE: Interpretation STATUS: Passed by J3 letter ballot QUESTION: Does the function IEEE_SUPPORT_DATATYPE (Section 14.8) override the mathematical equivalence rule (Section 7.1.8.3)? For example, could the program PROGRAM MAIN USE, INTRINSIC :: IEEE_ARITHMETIC USE, INTRINSIC :: IEEE_FEATURES X = 2.0 + 2.0 PRINT *, X END be executed as PROGRAM MAIN USE, INTRINSIC :: IEEE_ARITHMETIC USE, INTRINSIC :: IEEE_FEATURES X = 220.0*(1.0/55.0) PRINT *, X END if IEEE_SUPPORT_DATATYPE(X) is .TRUE.? Background: The committee recently ruled that 2.0 + 2.0 must produce the value 4.0 if IEEE_ARITHMETIC is in effect. I agree that if the particular operation the processor implements is addition of 2.0 and 2.0, the result must be 4.0. However, if IEEE_ARITHMETIC does not override the mathematical equivalence rule, the requirement is essentially meaningless, since there is no assurance that the expression in the program is the expression that will be evaluated. ANSWER: No, the mathematical equivalence rule is not overridden by USE of the IEEE_ARITHMETIC or IEEE_FEATURES modules. Doing so would prevent many benign and useful compiler optimizations and thus have an unnecessarily deleterious effect on performance. The mathematical equivalence displayed in the example is not a reasonable one, but deciding which mathematical equivalences are reasonable or not is outwith the scope of the standard. EDITS: None. SUBMITTED BY: Michael Ingrassia HISTORY: 06-124 m175 F03/0078 submitted 09-265 m189 Passed by J3 meeting 09-295 m190 Passed by J3 letter ballot #19 09-292 ---------------------------------------------------------------------- NUMBER: F03/0090 TITLE: Polymorphic array constructors KEYWORDS: polymorphic, array constructor DEFECT TYPE: Erratum STATUS: Passed by J3 letter ballot QUESTION: (1) Consider FUNCTION f1(dummy,n) CLASS(t) dummy TYPE(t) f1(n) f1 = [ (dummy,i=1,n) ] END FUNCTION Is this standard-conforming? (2) If the array constructor elements are polymorphic, is the array constructor polymorphic with the dynamic type of the elements? For example, consider FUNCTION f2(dummy,n) CLASS(t) dummy CLASS(t),ALLOCATABLE :: f2(:) IF (...) THEN ALLOCATE(f2(n),SOURCE=[(dummy,i=1,n)]) ! **1 ELSE ALLOCATE(f2(n),SOURCE=dummy) ! **2 END IF END FUNCTION The second ALLOCATE statement (marked **2) clearly allocates F2 with size N and the dynamic type of DUMMY. If the array constructor is polymorphic, the first ALLOCATE statement (marked **1) will have the same effect, otherwise it will allocate F2 with the dynamic type of F2 equal to the declared type of DUMMY. (3) If the array constructor is polymorphic, what is the dynamic type when multiple items have different dynamic types? ANSWER: (1) Yes. (2) No, it was not intended for array constructors to be polymorphic. A polymorphic array value, if desired, can be safely constructed by using an allocatable array function. (3) Not applicable. An edit is provided to clarify the situation. EDITS: [67:21] "same type" -> "same declared type" [68:9] "type and" -> "declared type and" [68:14+] Insert new paragraph "The dynamic type of the array constructor is the same as its declared type." SUBMITTED BY: Van Snyder HISTORY: 07-231 m180 F03/0090 submitted (revised by M. Cohen) 07-231 m180 Passed by J3 meeting 07-272 m181 Failed J3 letter ballot #13 07-250r1 09-266 m189 Revised answer - Passed by J3 meeting 09-295 m190 Passed as amended by J3 letter ballot #19 09-292 ---------------------------------------------------------------------- NUMBER: F03/0112 TITLE: Attributes allowed for dummy arguments in defined assignments KEYWORDS: defined assignment, dummy argument, attributes DEFECT TYPE: Erratum STATUS: Passed by J3 letter ballot INTRODUCTION: It seems the standard is quite loose in allowing various attributes declared for the dummy arguments used in a defined assignment (7.4.1.4). In particular, attributes such as POINTER and ALLOCATABLE can be declared for dummy arguments in the defined assignment. However the interpretations on their declarations need to be clarified. QUESTION: Consider the follow subroutines (assuming a derived type DT already defined) Q1. Are POINTER and ALLOCATABLE attributes allowed for the second dummy argument in defined assignment? interface ASSIGNMENT (=) subroutine defAssgn1 (dt1, dt2) type(DT), intent(out) :: dt1 type(DT), POINTER, intent(in) :: dt2 end subroutine end interface In 12.3.2.1.2 [263:10-12], the standard says the following "A defined assignment is treated as a reference to the subroutine, with the left-hand side as the first argument and the right-hand side enclosed in parentheses as the second argument." This statement seems to prohibit the use of subroutine defAssgn1 for defined assignment since a pointer enclosed in parentheses refers to its associated target not the pointer itself, as indicated by rules in 7.1.4.1 [123:39-124:3]. Q2. Are POINTER and ALLOCATABLE attributes allowed for the first dummy argument in defined assignment? interface ASSIGNMENT (=) subroutine defAssgn2 (dt1, dt2) type(DT), POINTER, intent(out) :: dt1 type(DT), intent(in) :: dt2 end subroutine end interface There are no rules in the standard that disallow this declaration. However the use of POINTER/ALLOCATABLE attributes on the first dummy argument is very doubtful. Since POINTER/ALLOCATABLE attributes don't disambiguate generic declarations(16.2.3), their use will prevent the normal declarations of defined assignments, wherein dt1 is declared without POINTER or ALLOCATABLE attribute. ANSWER: Yes to both questions. The interface blocks are not defective. The standard places very few restrictions on the arguments to defined assignment subroutines: [363:6...] Each of these subroutines shall have exactly two dummy arguments. Each argument shall be nonoptional. The first argument shall have INTENT (OUT) or INTENT (INOUT) and the second argument shall have INTENT (IN). ... Preventing the first argument from having the POINTER attribute violates F90. Preventing the second argument from having the ALLOCATABLE attribute would introduce a prohibition not specified by TR 15581, and might therefore be viewed as an incompatibility that ought to be announced in subclause 1.5. A program couldn't reference defAssgn1 by way of defined assignment because the right-hand side of a defined assignment is treated as an expression enclosed in parentheses which would have neither the POINTER nor the ALLOCATABLE attribute. A note is provided to draw the readers attention. EDITS: At the end of 12.3.2.1.2 insert a new NOTE 12.10+: "NOTE 12.10+ If the second argument of a procedure specified in a defined assignment interface block has the POINTER of ALLOCATABLE attribute, it cannot be accessed by defined assignment, since the right-hand side of the assignment is enclosed in parentheses before being associated as an actual argument with the second argument. This makes it an expression, which does not have the POINTER or ALLOCATABLE attribute." SUBMITTED BY: Jim Xia HISTORY: 08-120 m183 F03/0112 submitted 08-120r1 m183 Create answer 08-120r2 m183 Passed by J3 meeting 08-163 m184 Failed J3 letter ballot 08-141 08-186r1 m184 Another answer - Passed by J3 meeting 08-259 m185 Failed J3 letter ballot #17 08-213 08-263r1 m185 Revised answer - passed by J3 meeting 09-187r2 m188 Passed J3 letter ballot 09-155 F2008 note: edit is 09-007r1 [287:6-] 12.4.3.4.3 "Defined assignments" after NOTE 12.8 - edit passed at m188 ---------------------------------------------------------------------- NUMBER: F03/0119 TITLE: Elemental procedures and deferred length character components KEYWORDS: deferred length, elemental DEFECT TYPE: Erratum STATUS: Passed by J3 letter ballot QUESTION: Constraint C1279 says "In the scoping unit of an elemental subprogram, an object designator with a dummy argument as the base object shall not appear in a except as the argument to one of the intrinsic functions BIT_SIZE, KIND, LEN, or the numeric inquiry functions (13.5.6)." It has been stated in previous J3 papers that the reason for this restriction is to ensure that every iteration of a single invocation of an elemental procedure will have the same stack size: and this desire was achieved in Fortran 95. However, the situation changes with deferred-length character components. Consider example 1: PROGRAM example1 TYPE t CHARACTER(:),ALLOCATABLE :: cp END TYPE TYPE(t) array(100) DO i=1,100; array(i)%cp = REPEAT('x',i); END DO CALL zap(array) ... CONTAINS ELEMENTAL SUBROUTINE zap(x) TYPE(t),INTENT(INOUT) :: x REAL work(LEN(x%cp)) ... END SUBROUTINE END PROGRAM In the invocation "CALL zap(array)", the invoked procedure will have a different size for its WORK array for every element of ARRAY. Thus the restriction no longer achieves its aim (though this aim is not actually stated in the standard). However, as stated the restriction still prohibits the very similar program example2: PROGRAM example2 INTEGER :: array(100) = (/ (i,i=1,100) /) CALL es(array) PRINT *,array CONTAINS ELEMENTAL SUBROUTINE es(x) INTEGER,INTENT(INOUT) :: x REAL work(x) ... END SUBROUTINE END PROGRAM There does not seem to be any technical reason for the prohibition of example2. A more problematic case arises for an elemental function whose result variable has a length type parameter that depends on a deferred length parameter of a dummy argument. This can occur both for intrinsic type CHARACTER and for parameterized derived types. Consider: PROGRAM example3 TYPE t1(n) INTEGER,LEN :: n INTEGER istring(n) END TYPE TYPE t2 CHARACTER(:),ALLOCATABLE :: string END TYPE PRINT *,f( [ t2('short'),t2('this is much longer') ] ) CONTAINS ELEMENTAL FUNCTION f(x) TYPE(t2),INTENT(IN) :: x TYPE(t1(x%string%len)) f INTEGER j f%istring = [ (ICHAR(x%string(j:j),j=1,f%n)) ] END FUNCTION END The invocation of F in the PRINT statement will return an array whose elements have different length type parameters, something that is supposed to be impossible. Is this restriction still correct and useful? That is, (a) was example1 intended to be standard-conforming, (b) should example2 be standard-conforming, (c) was example3 intended to be standard-conforming. ANSWER: Although there is no technical (implementation) reason for prohibiting example2 while allowing example1, doing so is not a defect in the standard. However, allowing elemental functions to produce arrays whose elements have different length type parameters would be a defect. Thus, example1 is standard-conforming as argued; example2 is not conforming, because it violates constraint C1279; example3 was intended to be prohibited: an edit is supplied to fix this defect in the standard. EDIT: In 12.7.1, constraint C1278, [287:17] After "scalar" change "and" to a comma. [288:1] At the end of the sentence insert ", and shall not have a type parameter that is defined by an expression that is not an initialization expression". SUBMITTED BY: Malcolm Cohen HISTORY: 08-258 m185 F03/0119 submitted 08-299r1 m186 Revised answer, passed by J3 meeting 09-103 m187 Revised, passed by J3 meeting + F2008 fix 09-187 m188 Passed J3 letter ballot 09-155 as modified ---------------------------------------------------------------------- NUMBER: F03/0122 TITLE: When do objects of sequence derived type have the same type? KEYWORDS: SEQUENCE type DEFECT TYPE: Erratum STATUS: Passed by J3 letter ballot QUESTION: Consider the following program: MODULE MOD TYPE, PRIVATE :: T SEQUENCE INTEGER :: I END TYPE TYPE(T) :: X, Y CONTAINS SUBROUTINE S X = Y END SUBROUTINE S END PROGRAM MAIN USE MOD CALL S X = Y END The first sentence of subclause 4.5.1.3 of the 2003 Fortran standard says the program conforms because the objects X and Y have the same type, because they are declared by reference to the same type definition. The last sentence of that subclause says they do not have the same type because the type definition is declared to be PRIVATE. Does the program conform to the 2003 Fortran standard? If not, which assignment statement causes the program not to conform? ANSWER: The program conforms to the 2003 Fortran standard. ANALYSIS: The determination that an object cannot have the same type as another one that is declared by reference to a type that is declared to be PRIVATE cannot possibly refer to an object declared in a scope where the type is not accessible. Therefore the objects must be declared in scopes where the type is accessible. It is irrelevant whether the type is "declared to be PRIVATE" in that scope, because accessibility attributes determine whether a name is accessible in a different scope. It would be absurd if the assignment statement in the module subprogram were not standard conforming. Given that it must be standard conforming, it would be absurd if the assignment statement in the main program were not standard conforming. Edits are provided to clarify this conclusion. EDITS: In subclause 4.5.1.3 [47:11], remove "declared to be PRIVATE or" from the last sentence. SUBMITTED BY: Van Snyder HISTORY: 08-270 m185 F03/0122 submitted 08-270r1 m185 Passed by J3 meeting 09-187r2 m188 Passed J3 letter ballot 09-155 F2008 note: edit is 09-007r1 [63:10] 4.5.2.4 "Determination of derived types" remove "declared to be PRIVATE or" - edit passed at m188 --------------------------------------------------------------------- NUMBER: F03/0125 TITLE: Definitions of EXTENDS_TYPE_OF and SAME_TYPE_AS KEYWORDS: EXTENDS_TYPE_OF SAME_TYPE_AS DEFECT TYPE: Erratum STATUS: Passed by J3 letter ballot QUESTION: The arguments of EXTENDS_TYPE_OF and SAME_TYPE_AS are required to be of extensible type. Does this restriction apply to the declared type, the dynamic type, or both? ANSWER: This restriction was intended to apply to the dynamic type; this is clear from the existing text. However, the restriction is stronger than required or useful, and so an edit is supplied to weaken it. DISCUSSION: For EXTENDS_TYPE_OF, this is clear from the Result Value paragraph which explicitly specifies the result when either the A or MOLD argument to the intrinsic is unlimited polymorphic. For SAME_TYPE_AS, this is clear from Note 13.17 which explains how to work out the result when one or both arguments is a disassociated pointer (or unallocated allocatable), including that of an unlimited polymorphic entity. However, in the case of unlimited polymorphic, it is unreasonable to require the program to somehow know that the dynamic type is extensible; these functions should return the right result whenever either argument is of extensible type, and otherwise it should be processor dependent, i.e. the restriction should be weakened. EDITS: [316:16-17] In 13.7.38, EXTENDS_TYPE_OF, arguments A and MOLD, after "of extensible" change "type" to "declared type or unlimited polymorphic", twice. [316:21] Change the last "otherwise" to "if the dynamic type of A or MOLD is extensible,". [316:22] At the end of the sentence insert "; otherwise the result is processor dependent". [347:30,348:1] In 13.7.101, SAME_TYPE_AS, arguments A and B, after "of extensible" change "type" to "declared type or unlimited polymorphic", twice. [348:3] Change "The" to "If the dynamic type of A or B is extensible, the" [348:4] Append new sentence to paragraph "If neither A nor B have extensible dynamic type, the result is processor dependent." SUBMITTED BY: John Reid HISTORY: 08-281 m186 F03/0125 submitted 08-281r2 m186 Passed by J3 meeting + F2008 fix 09-187r2 m188 Passed by J3 letter ballot #18 09-155 ---------------------------------------------------------------------- NUMBER: F03/0126 TITLE: References to VOLATILE variables in pure procedures KEYWORDS: VOLATILE, PURE DEFECT TYPE: Erratum STATUS: Passed by J3 letter ballot QUESTION: Was it intended to allow a VOLATILE variable to be referenced in a pure procedure? ANSWER: No. It was intended that the result of invoking a pure function in a FORALL assignment statement should never depend on the order in which the invocations are executed, see NOTE 12.44. The value of a variable with the VOLATILE attribute might change between invocations of the function in ways incompatible with this design. EDIT: [286:22+] In 12.6, Pure procedures, add a new constraint: "C1271a The of a variable with the VOLATILE attribute shall not appear in a pure subprogram." SUBMITTED BY: John Reid and Bill Long HISTORY: 08-284 m186 F03/0126 submitted in response to N1745 by Nick Maclaren noting the problem 08-284r1 m186 Passed by J3 meeting {F2008 fixed in 12.7 "Pure procedures" 09-007 [317:14] C1281} 09-187r2 m188 Passed J3 letter ballot #18 09-155 ---------------------------------------------------------------------- NUMBER: F03/0127 TITLE: Duration of procedure execution KEYWORDS: argument association, procedure DEFECT TYPE: Erratum STATUS: Passed by J3 letter ballot QUESTION: In the following questions, the following type definition and procedure are assumed: TYPE T INTEGER :: C = 17 END TYPE SUBROUTINE S(A,B) TYPE(T),INTENT(IN) :: A TYPE(T),INTENT(OUT) :: B ... END (1) Consider TYPE(T) X X%C = 3 CALL S(X,X) Q1. Is this valid, and if so, is A%C equal to 3 or 17? Discussion: B is default-initialized "on invocation", and A is not permitted to be changed "during execution", so this depends on whether "during execution" was intended to include the process of invocation. (2) Consider TYPE(T) X X%C = 3 CALL S(F(),X) where F is the internal function TYPE(T) FUNCTION F() F = X END FUNCTION Q2. Is this valid? If so, what is the value of B%C (3 or 17)? Discussion: The reference to procedure F is not permitted to "affect or be affected by the evaluation of any other entity within the statement" (7.1.8 paragraph 3). However, X is not being affected by "evaluation" (it is not being evaluated by becoming argument- associated with dummy argument A). A becomes defined "on invocation" of S and it is not clear whether that precedes argument evaluation or not. (3) Consider SUBROUTINE V(AA,BB) TYPE(T),VALUE :: AA TYPE(T),INTENT(OUT) :: BB ... END TYPE(T) X X%C = 3 CALL V(X,X) Q3. Is this valid? If so, what is the value of AA%C (3 or 17)? Discussion: AA gets its value by argument association, so happens at the same time as the definition of BB (which defines the actual argument). It is not clear what the semantics are here. Q4. It is similarly unclear as to what is or is not permitted during invocation of a procedure when an actual argument might be modified by some other activity, for example if it has the VOLATILE or ASYNCHRONOUS attribute. ANSWER: The standard does not unambiguously supply an interpretation of these, and therefore they are invalid by subclause 1.5, first sentence. Edits are supplied to clarify this. EDITS: [81:15] 5.1.2.7, paragraph beginning "The INTENT(IN)", change "during the execution" to "during the invocation and execution". {Makes example 1 clearly invalid, and makes it clear that INTENT(IN) variables are unchanged from the start of invocation.} [81:26] Append to the INTENT(OUT) paragraph "Any undefinition or definition implied by association of an actual argument with an INTENT(OUT) dummy argument shall not affect any other entity within the statement that invokes the procedure." {Makes examples 2 and 3 clearly invalid.} [275:2,5] Change "during the execution" To "during the invocation and execution", Twice. {Makes it clear that the anti-aliasing rules apply for the whole process of procedure invocation and execution, not just the execution part.} SUBMITTED BY: Malcolm Cohen HISTORY: 08-298r1 m186 F03/0127 submitted 08-298r2 m186 Passed by J3 meeting + F2008 edit 09-187r2 m188 Passed J3 letter ballot #18 09-155 ---------------------------------------------------------------------- NUMBER: F03/0129 TITLE: C_LOC of character substrings KEYWORDS: interoperability DEFECT TYPE: Erratum STATUS: Passed by J3 letter ballot QUESTION: Consider SUBROUTINE S(A,I,K) USE ISO_C_BINDING CHARACTER(*),TARGET :: A CHARACTER(:),ALLOCATABLE,TARGET :: B TYPE(C_PTR) P1,P2,P3,P4,P5 P1 = C_LOC(A(1:1)) ! *1 P2 = C_LOC(A(I:I)) ! *2 P3 = C_LOC(A(1:)) ! *3 P4 = C_LOC(A(I:K)) ! *4 ALLOCATE(CHARACTER(1)::B) P5 = C_LOC(B) ! *5 END SUBROUTINE C_LOC (case 1) requires of its argument that it have interoperable type and type parameters (15.1.2.5, p395). Case 2 does not apply because character type has a length type parameter. 15.2.1 states "if the type is character, interoperability also requires that the length type parameter be omitted or be specified by an initialization expression whose value is one". However, a substring does not have a declared type parameter that can be omitted or specified by an initialization expression. Even in the reference marked *1, it is the substring starting and ending positions that are specified by initialization expressions, not the substring length. In any case, if *1 satisfied the quoted requirement then *3 also has its starting and ending positions specified by by initializations "or omitted". In case *2, it must be totally obvious that the length has to be 1 since the expressions are lexically identical with no user function references, but neither are initialization expressions. If I==K, it would be reasonable to expect *4 to be interoperable but it certainly does not satisfy the stated requirements. Or, another interpretation would be that for substrings the length type parameter is by definition "omitted" since they have no syntax for its specification: in which case the question would arise as to what happens for zero-length substrings. It seems that the authors of the requirement forgot that "variables" include "substrings". Finally, case *5 is totally ambiguous because B has multiple length specifications, one which does not satisfy the requirement (the declaration) and one which does (the ALLOCATE statement). ANSWER: C_LOC should only require nonzero length, which corresponds to the requirement we make for arrays. Furthermore, the description of interoperability of intrinsic types is confusing for type CHARACTER. Edits are provided to fix the defects. EDITS: [395:8(15.1.2.5)] In the <> paragraph, Before "type parameters" insert "kind". [395:16+] Insert new sentence after list: "X shall not be a zero-length string." [396:5-7] Replace "; if ... one." with ". If the type is character, the length type parameter is interoperable if and only if its value is one." {Reword so that the type/kind can be interoperable even if the length is not.} [399:2-3(15.2.4p1)] Before "scalar" insert "named", {I think this is supposed to be talking about named variables only, not about subobjects.} Change "if" to "if and only if" {Seems to be broken...} Change the second "and" to a comma, At the end of the sentence insert ", and if it is of type character its length is not assumed or declared by an expression that is not an initialization expression". {It seems more straightforward to forbid the invalid than to require the valid.} [399:7-8(15.2.5)] Change "An array Fortran variable" to "A Fortran variable that is a named array", Change "if" to "if and only if", Change the second "and" to a comma, At the end of the sentence insert ", and if it is of type character its length is not assumed or declared by an expression that is not an initialization expression". SUBMITTED BY: Malcolm Cohen HISTORY: 09-121r1 m187 F03/0129 submitted 09-121r1 m187 Passed by J3 meeting + F2008 fix 09-187r2 m188 Passed J3 letter ballot 09-155 as modified ---------------------------------------------------------------------- NUMBER: F03-0130 TITLE: Elemental specific intrinsic procedure characteristics KEYWORDS: Elemental intrinsic, procedure pointer, dummy procedure DEFECT TYPE: Interpretation STATUS: Passed by J3 letter ballot QUESTION: (1) Are the specific intrinsic procedures (listed in 13.6 and not marked with a bullet) elemental or nonelemental? (2) What rank do those specific intrinsic procedures have? (3) May one of those procedures become associated with a dummy procedure or procedure pointer with nonzero rank? (4) When one of these procedures is associated with a dummy procedure or procedure pointer, does it still have the elemental property? ANSWER: (1) Those specific intrinsic procedures are elemental. (2) They are elemental functions; thus they are scalar in themselves, but may be applied to an array in which case the reference will be an array. (3) No. As elemental procedures, by definition the dummy arguments and result have rank zero. This does not satisfy the requirements for procedure argument or procedure pointer association. (4) The specific intrinsic procedure itself retains the elemental property (so a reference using its own name can be elemental), but the dummy procedure or procedure pointer associated with it is not elemental and so cannot be used to reference the specific intrinsic procedure elementally. EDIT: None. SUBMITTED BY: Van Snyder HISTORY: 09-171r1 m188 F03/0130 submitted 09-217 m188 Revised question/answer - passed by J3 meeting 09-xxx m190 Passed by J3 letter ballot #19 09-292 ---------------------------------------------------------------------- NUMBER: F03/0131 TITLE: SAVE attribute and EQUIVALENCE KEYWORDS: SAVE, EQUIVALENCE DEFECT TYPE: Erratum STATUS: Passed by J3 letter ballot QUESTION: If one object in an EQUIVALENCE set has the SAVE attribute, do all the other objects in the EQUIVALENCE set implicitly have the SAVE attribute? This can be detected by the program: SUBROUTINE s1 TYPE T SEQUENCE REAL :: C = 3.0 END TYPE TYPE(t) x,y SAVE x EQUIVALENCE(x,y) x = t(1.0) RETURN ENTRY s2 PRINT *,y ! Does this print 1.0 or 3.0? END PROGRAM show CALL s1 CALL s2 END If Y has the SAVE attribute the program will print 1.0; if not, it will print 3.0 due to the default initialization. ANSWER: Yes, the SAVE attribute propagates through EQUIVALENCE. An edit is supplied to clarify this. EDIT: [97:7+] Insert new paragraph "If any data object in an has the SAVE attribute, all other objects in the have the SAVE attribute; this may be confirmed by explicit specification." SUBMITTED BY: Malcolm Cohen HISTORY: 09-194 m188 F03/0131 submitted 09-194r1 m188 Passed by J3 meeting 09-xxx m190 Passed by J3 letter ballot #19 09-292 ---------------------------------------------------------------------- NUMBER: F03/0132 TITLE: Unformatted i/o and private components KEYWORDS: UNFORMATTED, INPUT/OUTPUT, PRIVATE DEFECT TYPE: Erratum STATUS: Passed by J3 letter ballot QUESTION: Consider Module M Type T Private Real :: UDATA(100) End Type End Module ... Type(T) X ... Write (10,*) X ! Formatted Write Write (20) X ! Unformatted Write Both of the WRITE statements were not valid Fortran 95. Are either of them valid Fortran 2003? According to [193:9-12], the formatted WRITE statement is not valid. But the corresponding paragraph for unformatted WRITEs, at [193:1-5], only forbids private components when some component of T would itself be handled by user-defined derived-type input/output. That does not seem to be consistent. DISCUSSION: The "shall not be pointers or allocatables" part of the [193-:1-5] paragraph is repeated later, at [193:13-15]. This makes no mention of accessibility. ANSWER: Both cases were intended to be invalid. An edit is supplied to repair the requirements for unformatted i/o. EDIT: [193:13-15] Replace paragraph "If a derived-type list item is not processed by a user-defined derived-type input/output procedure and is not treated as a list of its individual components, all the subcomponents of that list item shall be accessible in the scoping unit containing the input/output statement and shall not be pointers or allocatable". SUBMITTED BY: Malcolm Cohen HISTORY: 09-195 m188 F03/0132 submitted - passed by J3 meeting 09-xxx m190 Passed by J3 letter ballot #19 09-292 ---------------------------------------------------------------------- NUMBER: F03/0133 TITLE: Is unlimited polymorphic allowed in COMMON? KEYWORDS: Unlimited polymorphic, CLASS(*), COMMON DEFECT TYPE: Erratum STATUS: Passed by J3 letter ballot QUESTION: For a pointer to a derived type to be storable in COMMON, it must be of sequence type. However, there does not seem to be any prohibition against a CLASS(*) pointer in COMMON. Is this allowed? ANSWER: This was inadvertently allowed in the Fortran 2003 standard as published. An edit is supplied to correct this error. EDIT: [98:22] After "BIND attribute," insert "an unlimited polymorphic pointer," SUBMITTED BY: Malcolm Cohen HISTORY: 09-204 m188 F03/0133 submitted - passed by J3 meeting 09-xxx m190 Passed by J3 letter ballot #19 09-292 ---------------------------------------------------------------------- NUMBER: F03/0134 TITLE: Implicit typing of procedure pointers KEYWORDS: procedure pointer, implicit type DEFECT TYPE: Erratum STATUS: Passed by J3 letter ballot QUESTION: Q1. Are procedure pointer components implicitly typed? That is, considering PROGRAM implicitppc EXTERNAL proc TYPE t PROCEDURE(),POINTER,NOPASS :: ptr END TYPE t TYPE(t) :: i i%ptr => proc PRINT *,i%ptr() END PROGRAM is this program standard-conforming and if so, what is the type of the procedure pointer component PTR? In J3/04-007 one finds (p. 93, ll. 8-11) 5.3 "Any data entity that is not explicitly declared by a type declaration statement, is not an intrinsic function, and is not made accessible by use association or host association is declared implicitly to be of the type (and type parameters) mapped from the first letter of its name, provided the mapping is not null." Q2. Are ambiguous procedure pointers allowed? That is, considering SUBROUTINE ppOne(do_the_subroutine) LOGICAL :: do_the_subroutine EXTERNAL some_subroutine, some_function PROCEDURE(), POINTER :: proc_pointer IF (do_the_subroutine) THEN proc_pointer => some_subroutine CALL proc_pointer(5) ELSE proc_pointer => some_function y = proc_pointer(7) END IF END SUBROUTINE (a) Does the subroutine ppOne conform to the Fortran standard? (b) If yes, does a subroutine with the "if"/"else"/"end if" lines removed conforms to the standard? In J3/04-007 one finds (p. 145, ll. 2-4) 7.4.2.2 "If proc-pointer-object has an implicit interface and is explicitly typed or referenced as a function, proc-target shall be a function. If proc-pointer-object has an implicit interface and is referenced as a subroutine, proc-target shall be a subroutine." Q3. If ambiguously-typed procedure pointers are allowed, are they still allowed with IMPLICIT NONE? That is, considering IMPLICIT NONE ! p is not implicitly typeable REAL, EXTERNAL :: func PROCEDURE(), POINTER :: p1 PROCEDURE(REAL),POINTER :: p2 REAL y p1 => func ! A p2 => p1 ! B y = p2() END PROGRAM are the procedure pointer assignments A and B standard-conforming? In J3/04-007 one finds (p.146, ll. 36-38; p. 145, ll. 2-6) 7.4.2.2 Procedure pointer assignment "If the proc-target is not a pointer, proc-pointer-object becomes pointer associated with proc-target. Otherwise, the pointer association status of proc-pointer-object becomes that of proc-target; if proc-target is associated with a procedure, proc-pointer-object becomes associated with the same procedure. [...] If proc-pointer-object has an implicit interface and is explicitly typed or referenced as a function, proc-target shall be a function. If proc-pointer-object has an implicit interface and is referenced as a subroutine, proc-target shall be a subroutine. If proc-target and proc-pointer-object are functions, they shall have the same type; corresponding type parameters shall either both be deferred or both have the same value." ANSWER: (1) No, procedure pointer components are never implicitly typed. The quoted text from the standard does not apply to components; if it did apply to components, data components would also be implicitly typed and that would be a contradiction. A clarifying edit is provided. (2) Yes, ambiguous procedure pointers are allowed. However, a procedure pointer is only ambiguous if it is neither referenced as a subroutine nor as a function. Therefore, as the quoted text from the standard indicates, the example is not conforming. (3) No, a procedure pointer with no type can only be ambiguous if there is a valid implicit type mapping for the initial letter of its name. Therefore, with IMPLICIT NONE, PROCEDURE() declares a subroutine with an implicit interface, the same as EXTERNAL. EDITS: [93:9] After "function," insert "is not a component,". {Components are never implicitly typed.} SUBMITTED BY: Tobias Burnus HISTORY: 09-236 m189 F03/0134 submitted 09-236r1 m189 Passed by J3 meeting 09-xxx m190 Passed by J3 letter ballot #19 09-292 ---------------------------------------------------------------------- NUMBER: F03/0135 TITLE: Interaction between RESULT, recursion, and host generic KEYWORDS: RESULT, generic, recursion DEFECT TYPE: Interpretation STATUS: Passed by J3 letter ballot QUESTION: Consider MODULE example INTERFACE f MODULE PROCEDURE f0,f END INTERFACE CONTAINS INTEGER FUNCTION f0(n) RESULT(y) y = n + 1 END FUNCTION INTEGER FUNCTION f(n1,n2) RESULT(y2) y2 = f(n1+n2) END FUNCTION END MODULE Q1. Does the reference to F in the assignment to Y2 refer to the generic F (and is thus a valid reference to F0) or to the specific F (and is thus an invalid recursive reference to itself with the wrong number of arguments)? Section 12.5.2.1 (Function subprogram, at lines 31-33 on page 296) states: "If RESULT is specified, [...] all occurrences of the function name in execution-part statements in the scoping unit refer to the function itself." That would appear to indicate that it is a reference to the specific F itself, and thus invalid. How should the rules in 12.4.4 for resolving named procedure references be applied to this? In particular, for the reference to F from within F, Q2. Is F established to be generic by rule (1)(d)? If so, that should mean that the reference to F within itself is a valid reference to the generic F (then resolved to F0). Q3. Is F established to be specific by rule (2)(e)? Even if F is not established to be generic, if it is established to be specific then the subsequent rule (6) in 12.4.4.2 means the reference is valid, being resolved via host association to the generic F (then resolved to F0). Q4. If F is not established, then rule (3) in 12.4.4.3 indicates the reference would be to the external procedure F. That does not seem to make sense. Consider the case where F instead looks like this: RECURSIVE INTEGER FUNCTION f(n1,n2) RESULT(y2) IF (n1>1 .AND. n2>1) THEN y2 = f(n1-1,n2-1) ELSE y2 = MAX(n1,n2) END IF END FUNCTION This would appear to be a valid subprogram using the interpretation in 12.5.2.1 (that F is a reference to itself), but if F is not established then it would not be valid. Q5. Is this example conforming? ANSWER: (1) The analysis is correct, the use of F within the function F is, as stated, a reference to F itself (and thus the example is invalid). (2) F is not established to be generic: it contains a declaration of F (the FUNCTION statement itself) so the generic in the host in the rule (1)(d) does not apply. (3) According to the rules as they are now, F is not established to be specific: rule (2)(e) is inapplicable because the FUNCTION statement is a declaration of F. This is an error in the standard. (4) You are correct, that would not make sense. This is an error in the standard. (5) You are correct, these rules are contradictory. The intent was that this example should be conforming. Edits are supplied to correct the rules in 12.4.4 to account for recursive self-references to functions with RESULT clauses. The function F should be established to be specific, and the reference should be to itself. EDITS: [276:36+] Insert new case "(a2) if the scoping unit is a subprogram that defines a procedure with that name;" {Establish the name to be (only) specific.} [278:15+] Insert new case "(3a) If the scoping unit is a subprogram that defines a procedure with that name, the reference is to that procedure." {Resolve to the procedure.} SUBMITTED BY: Tobias Burnus HISTORY: 09-237 m189 F03/0135 submitted 09-237r1 m189 Passed by J3 meeting 09-xxx m190 Passed by J3 letter ballot #19 09-292 ---------------------------------------------------------------------- NUMBER: F03/0136 TITLE: Are subroutines distinguishable from arrays? KEYWORDS: Generic resolution, subroutine, array DEFECT TYPE: Erratum STATUS: Passed by J3 letter ballot QUESTION: Can a subroutine be used as a disambiguator in a generic reference? A subroutine cannot reliably be distinguished from a scalar function because of implicit typing. However, it can always be distinguished from an array function, because an array function needs to have an explicit interface that provides its rank (and type, but rank is the important consideration for this question). For generic resolution, the Fortran 95 standard allowed a dummy argument to be a "disambiguator" if it had a different data type, kind type parameter, or rank (14.1.2.3, page 277). There is no clear definition of what the rank of a subroutine is, but many have assumed that the rank of a subroutine is zero; thus allowing "subroutine vs. array" to be used to disambiguate generic references. However, this text was changed in Fortran 2003 to forbid a subroutine from ever being used as a disambiguator (16.2.3, page 407). Here is an example: Module example Interface gen Module Procedure invoke,aprint End Interface Contains Subroutine invoke(s) External s Call s ! We know this is a subroutine. End Subroutine Subroutine aprint(a) Real a(:) Print *,'[',a,']' End Subroutine End Module It is clear that if the Call s statement were changed to Print *,s() then the module would be standard-conforming. It seems inconsistent to allow scalar functions to disambiguate with arrays but to disallow subroutines from disambiguating with arrays. DISCUSSION: In Fortran 2008, procedureness is a potential disambiguator which would make the above simple example conforming, but there is still a problem with Module example Interface gen Module Procedure invoke,aprint End Interface Contains Subroutine invoke(s,n) External s Call s(n) ! We know this is a subroutine. End Subroutine Subroutine aprint(af,n) Interface Function af(n) Real af(n) End Function End Interface Print *,'[',af(n),']' End Subroutine End Module Again, changing "Call s(n)" to "Print *,s(n)" would make the example conform to the standard as written. ANSWER: This inconsistency was inadvertant. Edits are supplied to correct this oversight. EDITS: [407:28] After "distinguishable if" insert "one is a subroutine and the other is an array, or if". SUBMITTED BY: Malcolm Cohen. HISTORY: 09-264 m189 F03/0136 submitted - Passed by J3 meeting 09-xxx m190 Passed as amended by J3 letter ballot #19 09-292 ---------------------------------------------------------------------- NUMBER: F03/0137 TITLE: Dummy procedure type compatibility KEYWORDS: Dummy function, implicit interface DEFECT TYPE: Interpretation STATUS: Passed by J3 letter ballot QUESTION: Consider PROGRAM EXAMPLE REAL,EXTERNAL :: F CALL S(F) END SUBROUTINE S(A) INTEGER,EXTERNAL :: A PRINT *,A() END SUBROUTINE REAL FUNCTION F() F = HUGE(0.0) END FUNCTION Subclause 12.4.1.3 (pages 271-272) appear to require that the actual argument corresponding to a procedure dummy argument must be a function if the dummy procedure is referenced as a function, but there seems to be no visible requirement for it to have the same type and type parameters. That would seem to make the above program standard conforming. Is there intended to be such a requirement? ANSWER: Yes, there should be such a requirement. An edit is supplied to correct this oversight. EDIT: [271:28] Append new sentences to the end of paragraph 5 of 12.4.1.3 "If both the actual argument and dummy argument are known to be functions, they shall have the same type and type parameters. If only the dummy argument is known to be a function, the function that would be invoked by a reference to the dummy argument shall have the same type and type parameters, \obs{except that an external function with assumed character length may be associated with a dummy argument with explicit character length}". {The second sentence is there to catch an argument association chain, and this case needs to allow the obsolescent assumed-length character function. In the case in the first sentence, the actual argument already is prevented from having assumed length by our other rules.} SUBMITTED BY: Malcolm Cohen HISTORY: 09-267 m189 F03/0137 submitted - Passed by J3 meeting 09-xxx m190 Passed by J3 letter ballot #19 09-292 ---------------------------------------------------------------------- NUMBER: F03/0138 TITLE: External as KEYWORDS: procedure name, procedure pointer, procedure pointer assignmant DEFECT TYPE: Erratum STATUS: Passed by J3 letter ballot QUESTION: 7.4.2 C727 says a " [that is a ] shall be the name of an external ... procedure...." To be passed as an actual argument, a procedure needs to have the EXTERNAL attribute, but there appears to be no such requirement for being a target in a procedure pointer assignment. (1) Is the following example standard-conforming? PROGRAM example1 PROCEDURE(),POINTER :: p PROCEDURE(REAL),POINTER :: q p => x CALL x q => y PRINT *,y(5) CALL p PRINT *,q(5) END SUBROUTINE x PRINT *,'ok so far' END FUNCTION y(n) y = SQRT(REAL(n)) END (2) If example1 is standard-conforming, is this example conforming? MODULE exmod PROCEDURE(),POINTER :: p CONTAINS SUBROUTINE test CALL p END SUBROUTINE END PROGRAM example2 USE exmod p => x CALL test END SUBROUTINE x PRINT *,'ok' END ANSWER: (1) Yes, this example is conforming. As correctly noted, there is no requirement for the EXTERNAL attribute in a procedure pointer assignment, and both X and Y are known within the main program to be external procedures. (2) This example was not intended to be conforming. An edit is provided to clarify this. EDIT: [144:5-6] In 7.4.2 Pointer assignment, constraint C727, Change "an external, module," to "a module", Change "or a procedure pointer" to "a procedure pointer, or an external procedure that is accessed by USE or host association, referenced in the scoping unit as a procedure, or that has the EXTERNAL attribute". SUBMITTED BY: Van Snyder HISTORY: 09-281 m189 F03/0138 submitted - Passed by J3 meeting 09-xxx m190 Passed by J3 letter ballot #19 09-292 ---------------------------------------------------------------------- NUMBER: F03/0139 TITLE: Functions returning procedure pointers KEYWORDS: procedure pointer DEFECT TYPE: Erratum STATUS: Passed by J3 letter ballot QUESTION: (1) Is a function permitted to return a procedure pointer? Much of the language talks about the function result variable, but a procedure pointer is not a variable. For example, 2.2.3 says [12:16] "The VARIABLE that returns the value of a function is called the RESULT VARIABLE." (emphasis mine); which indicates that the value of a function is returned in a variable. (2) Where may a function reference that returns a procedure pointer appear? In particular, (a) as a in a SELECT TYPE or an ASSOCIATE statement; (b) within parentheses as a primary; (c) as the argument to an intrinsic inquiry function such as KIND or LEN. (3) [12:18-19] says "a subroutine may be used to change the program state by changing the values of any of the data objects accessible to the subroutine". A procedure pointer is not a data object, so is this meant to imply that a subroutine is not permitted to change the state of a procedure pointer? Similar text for functions appears in the same paragraph. ANSWER: (1b) Yes, a function is permitted to return a procedure pointer; the text calling this a variable is in error. Edits are supplied to correct these mistakes. (2b) It was intended that a function reference that returns a procedure pointer only be permitted as an argument to the ASSOCIATED and NULL intrinsic functions and in places where an ordinary procedure name would be acceptable. Parentheses around a pointer act to dereference the pointer and return a copy of the value: this action is inapplicable to procedures. Thus the answers to the specific sub-questions are No, No, and No again. Clarifying edits are provided. (3) No, this implication should not be drawn. A clarifying edit is provided. EDITS for (1b): [12:16] Change "The variable that ... the result variable" to "The entity that ... the function result". [75:13] After "function result" delete "variable". [93:16] After "of the result" delete "variable". [115:7] After "function result" delete "variable". [280:18-19] After "name of the result" delete "variable". [280:22] After "name of the result" delete "variable". [280:31] After "name of the result" delete "variable". [280:33] After "not specified, the" Change "result variable" to "name of the result". [280:34] After "references to the result" delete "variable". [280:34-35] Delete "The characteristics ... the result variable.". [280:36] After "that of its result" change "variable" to "entity". [280:36] Change "is a pointer" to "is a data pointer", [280:37] After "shape of the result" delete "variable". [280:38] Change "result variable" to "function result". [280:39] After "with the result" delete "variable". [280:40+] In Note 12.37, Change "variable" to "entity" four times. [283:20] After "name of its result" delete "variable". [283:22] Change "result variable" to "result name". [283:25] Change "result variables identify the same variable" to "result names identify the same entity" and delete ", although their names need not be the same". [287:17] After "The result" delete "variable". [400:7] "result variable is a scalar"->"result is a scalar object". [407:8] After "identify the result" delete "variable". [407:12-13] After "identify the result" delete "variable". [407:21-22] "result variable" -> "named result entity which is either a variable or a procedure pointer". [407:22-23] Change "variable" to "entity" twice. [415:40] Change "result variables" to "function results that are variables". [417:18] Change "of the result" to "of the result entities if they are variables". [423:14] "The result variable of a function" ->"The result of a function that returns a data object". [430:13] "data object"->"entity". [434:10] Delete whole line. EDITS for (2b). [117:27+] Insert new constraint "C703 (R701) The shall not be a function reference that returns a procedure pointer." [160:17+] Insert new constraint "C809a (R819) The shall not be a function reference that returns a procedure pointer." [292:8+] Insert new paragraph "An argument to an intrinsic procedure other than ASSOCIATED, NULL, or PRESENT shall be a data object." EDITS for (3). [12:19] After "data objects" insert "or procedure pointers". SUBMITTED BY: Malcolm Cohen HISTORY: 09-295 m190 F03/0139 submitted - Passed by J3 meeting: B answers passed 10-105 m191 Passed as amended by J3 letter ballot #20 09-307 ---------------------------------------------------------------------- NUMBER: F03/0140 TITLE: Type of nested construct entities. KEYWORDS: ASSOCIATE, DATA, FORALL, SELECT TYPE DEFECT TYPE: Erratum STATUS: Passed by J3 letter ballot QUESTION: Consider the example: PROGRAM bad REAL x INTEGER i,y(10) ASSOCIATE (x=>i) ! B DATA (y(x),x=1,10)/10*1/ ! A DO x=1,10 ! B y(x) = SQRT(y(x)) ! B END DO ! B FORALL(x=1:10) y(x) = y(x)**2 ! C END ASSOCIATE ! B x = SUM(y) END PROGRAM Is this program conforming? That is: Within the ASSOCIATE construct, is X of type INTEGER? It certainly is in the statements marked with "! B". But according to 16.3 paragraph 2 [409:18-20], in the statement marked "! A", X has the type it has in the scoping unit, which would have to be REAL. And according to 16.3 paragraph 3 [409:25-27], in the statement marked "! C", X has the type it has in the scoping unit, which would have to be REAL. If X is type REAL for DATA and FORALL, the program would not be conforming, but it would be if X were of type INTEGER. ANSWER: Within the scope of a construct entity name, it was intended that a data-implied-do index or a FORALL index name should have the type and type parameters of the construct entity name. Edits are provided to clarify this. EDITS: [409:19] 16.3 Statement and construct entities, para 2, sentence 2, Before "scoping unit" insert "innermost executable construct or". {Makes a difference for DATA in ASSOCIATE and SELECT TYPE only.} [409:26] 16.3, paragraph 3, sentence 2, Before "scoping unit" insert "innermost executable construct or". {Makes a difference for FORALL in ASSOCIATE and SELECT TYPE only.} SUBMITTED BY: Malcolm Cohen HISTORY: 09-301 m190 F03/0140 submitted - Passed by J3 meeting 10-105 m191 Passed by J3 letter ballot #20 09-307 ---------------------------------------------------------------------- NUMBER: F03/0141 TITLE: More than one specific interface for a procedure KEYWORDS: Specific interface DEFECT TYPE: Erratum STATUS: Passed by J3 letter ballot QUESTION: Consider the example: module A contains subroutine S ( X ) real :: X end subroutine S end module A module B use A, only: T => S end module B module C use A, only: U => S end module C program P use B ! Access the procedure name T use C ! Access the procedure name U ! T and U are different names for the same procedure. end program P Is this program conforming? The procedure S defined in the module A has two explicit specific interfaces in program P. The sixth paragraph after constraint C1211 in subclause 12.3.2.1 says "A procedure shall not have more than one explicit specific interface in a given scoping unit." ANSWER: It was intended that this program be conforming. An edit is provided to correct this. EDITS: [260:1 last sentence of sixth paragraph after constraint C1211 in subclause 12.3.2.1] Insert "name" after "procedure". SUBMITTED BY: Van Snyder HISTORY: 09-304 m190 F03/0141 submitted - Passed by J3 meeting 10-105 m191 Passed by J3 letter ballot #20 09-307 ----------------------------------------------------------------------