[J3] (SC22WG5.6288) WG5 letter ballot 1 on Fortran 2018 interpretations
Steve Lionel
steve at stevelionel.com
Thu Sep 24 19:02:39 EDT 2020
ISO/IEC JTC1/SC22/WG5 N2176
WG5 letter ballot 1 on Fortran 2018 interpretations
Steve Lionel, September 24, 2020
This is the first set of draft interpretations for Fortran 2018. They
have all been approved in a J3 letter ballot.
The rules we operate on say:
4. The chair of J3/interp gathers all interp answers that are marked
"passed by J3 letter ballot" and forwards them to the WG5 convenor.
The WG5 convenor holds a ballot of individual members; a no vote
must be accompanied by an explanation of the changes necessary to
change the member's vote to yes. The answers that pass this ballot
become "WG5 approved".
J3/interp reserves the right to recall an interp answer for more
study even if the answer passes.
5. "WG5 approved" answers are processed into a corrigendum document by
taking the edits from the interp answers and putting them in the
format required by ISO. A WG5 vote is made on forwarding the
corrigendum to SC22.
The following Fortran 2018 interpretations are being balloted:
Yes No Number Title
--- --- F18/001 ACOSH principal value specification is wrong
--- --- F18/002 Internal procedures in generic interface blocks
--- --- F18/003 Pointer association of component of non-definable selector
--- --- F18/004 Program execution sequence with failed images
--- --- F18/005 Does INPUT_UNIT really identify the same unit as *?
--- --- F18/006 Connection of INPUT_UNIT on different images
--- --- F18/008 Contradictory assumed-rank requirements
--- --- F18/009 Bad examples in IEEE_ARITHMETIC functions
--- --- F18/010 Categories of pure procedures
--- --- F18/011 Categories of elemental procedures
--- --- F18/012 Internal procedure in a generic interface
--- --- F18/013 TEAM_NUMBER arguments and intrinsic function are ambiguous
--- --- F18/014 Type of OPERATION arguments to the REDUCE intrinsic
--- --- F18/015 Example in C.6.8 is wrong
--- --- F18/016 Host association changes in Fortran 2018
--- --- F18/017 Final subroutine invocation order
--- --- F18/018 Public namelist and private variable
The text of these interpretations appears below.
Each interpretation starts with a row of "-"s.
Please mark the above -Y- in the Yes column for "yes", -C- in the Yes
column for "yes with comment", or -N- in the No column for a "no"
answer {be sure to include your reasons with "no"} and send ONLY the
vote section to
sc22wg5 at open-std.org
by 0001 Las Vegas time on October 24, 2020, in order to be counted.
Thanks,
Steve
----------------------------------------------------------------------
NUMBER: F18/001
TITLE: ACOSH principal value specification is wrong
KEYWORDS: ACOSH
DEFECT TYPE: Erratum
STATUS: Passed by J3 letter ballot
QUESTION:
Clause 16.9.5 ACOSH( X ) p5 Result Value has:
"If the result is complex the imaginary part is expressed in
radians and lies in the range 0 <= AIMAG (ACOSH (X)) <= {pi}".
There is general agreement that the principal value of ACOSH should
have the real part non-negative which means the imaginary part must
range from -pi to +pi.
Is this a mistake in the definition of ACOSH?
ANSWER:
Yes, this is a mistake. Edits are included to correct this error.
This will be an incompatibility with Fortran 2008.
EDITS to 18-007r1:
[26:17+] 4.3.3 Fortran 2008 compatibility, p10+, insert new para
"Fortran 2008 required ACOSH of a complex value to have the
imaginary part nonnegative and had no requirement on
the real part. This document requires ACOSH of a complex
value to have a nonnegative real part and has no such
requirement on the imaginary part."
[340:34-35] 16.9.5 ACOSH, p5 Result Value,
after "is complex"
insert "the real part is nonnegative and",
change "range 0" to "range $-\pi$".
Making the whole p5 read
"Result Value. The result has a value equal to a processor-
dependent approximation to the inverse hyperbolic cosine
function of X. If the result is complex the real part is non-
negative, and the imaginary part is expressed in radians and
lies in the range $-\pi$ <= AIMAG (ACOSH (X)) <= $\pi$."
SUBMITTED BY: Anton Shterenlikht
HISTORY: 18-236 m217 Submitted
18-236r1 m217 Put into interp format, revised edits.
18-236r2 m217 Revised draft - Passed by J3 meeting
19-228 m220 Passed as amended by J3 letter ballot #35
----------------------------------------------------------------------
----------------------------------------------------------------------
NUMBER: F18/002
TITLE: Internal procedures in generic interface blocks
KEYWORDS: Internal procedure, generic interface block
DEFECT TYPE: Erratum
STATUS: Passed by J3 letter ballot
QUESTION:
An internal procedure is allowed in a GENERIC statement, but
apparently it cannot appear in a generic interface block.
Section 15.4.3.4.1 (12.4.3.4.1 in F2008) Generic identifiers p1 states
"A generic interface block specifies a generic interface for each
of the procedures in the interface block. The PROCEDURE statement
lists procedure pointers, external procedures, dummy procedures,
or module procedures that have this generic interface."
Is the apparent prohibition of internal procedures in the PROCEDURE
statement intended?
ANSWER:
No, this was not intended. An internal procedure should be allowed
in a generic interface body. An edit is provided to correct this
mistake.
DISCUSSION:
In F2003, Section 12.3.2.1 Interface Block has rule R1206
<procedure-stmt> is [MODULE] PROCEDURE <procedure-name-list>
with constraint C1270
"A <procedure-name> shall have an explicit interface and shall
refer to an accessible procedure pointer, external procedure,
dummy-procedure, or module procedure."
Edits in paper 05-202r1 allowed internal procedures to be passed as
actual arguments and to be targets of procedure pointers. This meant
an internal procedure could be the target of a procedure pointer
which was specified in a generic interface body.
Paper 08-178 asked the question "What is the point of excluding
internal procedure in C1207?" and replaced C1207 with
"A <procedure-name> shall be a nonintrinsic procedure that has an
explicit interface."
The normative text cited in the question was not modified.
This was an oversight.
EDIT to 18-007r1:
[294:11-12] 15.4.3.4.1 Generic identifiers, p1, second sentence,
Change "procedure pointers, external procedures, dummy
procedures, or module procedures"
to "nonintrinsic procedures with explicit interfaces".
This makes the sentence read:
"The PROCEDURE statement lists nonintrinsic procedures with explicit
interfaces that have this generic interface."
SUBMITTED BY: Jon Steidel
HISTORY: 18-251 m217 Submitted
18-251r1 m217 Revised draft - Passed by J3 meeting
n/a n/a Typos noted at meeting corrected by /Interp.
19-228 m220 Passed by J3 letter ballot #35
----------------------------------------------------------------------
----------------------------------------------------------------------
NUMBER: F18/003
TITLE: Pointer association of component of non-definable selector
KEYWORDS: Pointer association, Associate name
DEFECT TYPE: Erratum
STATUS: Passed by J3 letter ballot
QUESTION:
Consider the following
type :: T
real, pointer :: X
end type T
type(t), external :: F
real, target :: P
associate ( A => F(42) )
nullify ( A%X ) !***
A%X => P !***
end associate
The topic is whether the statements marked "!***" (the NULLIFY
statement and the pointer assignment statement) conform to the
standard.
11.1.3.3p5 ([175:18-21] of 18-007r1) has two requirements that are
relevant to this topic:
"The associating entity itself is a variable, but if the selector
is not a definable variable, the associating entity is not
definable and shall not be defined or become undefined. If a
selector is not permitted to appear in a variable definition
context (19.6.7), neither the associate name nor any subobject
thereof shall appear in a variable definition context."
With regards to the second sentence, neither NULLIFY nor a pointer
assignment statement is a variable definition context (19.6.7,
[516:12-30] lists fifteen variable definition context: neither
statement appears in the list. Therefore it seems that this
requirement is satisfied.
With regards to the first sentence, the associate-name A "shall not
be defined or become undefined". It appears that neither of these
statements cause A to be defined or become undefined, because
(a) An object of derived type is defined if and only all of its
nonpointer components are defined (see 19.6.1p4, [511:11]).
The pointer association status of the component A%X is thus
irrelevant to the question of whether A is defined.
(b) Neither statement appears anywhere in the giant lists of "Events
that cause variables to become defined" (or "undefined") in
19.6.5 and 19.6.6.
Therefore we must reluctantly conclude that the requirements of the
first sentence also appear to be satisfied.
Against this, it is certainly true that the *value* of A is affected
by the statements in question: see 7.5.8 Derived-type values, which
states that the "component value" of a pointer component is its
association status, and
"The set of values of a particular derived type consists of all
possible sequences of the component values..."
However, there is no rule in 11.1.3.3 about changing the values, even
though it might seem contradictory that something that changes the
value of an undefinable object would be permitted.
So the question is, are the two statements standard-conforming?
ANSWER:
No, these statements were not intended to be standard-conforming.
The lack of an explicit rule is an error in the standard.
An edit is provided to correct this error.
EDIT to 18-007r1:
[175:21] 11.1.3.3 Other attributes of associate names, p5,
After "variable definition context"
insert " or a pointer association context",
making the whole paragraph read:
"The associating entity itself is a variable, but if the selector
is not a definable variable, the associating entity is not
definable and shall not be defined or become undefined. If a
selector is not permitted to appear in a variable definition
context (19.6.7), neither the associate name nor any subobject
thereof shall appear in a variable definition context or pointer
association context."
{Prohibit the marked statements.
The extra context is only relevant to pointer subobjects, but this
need not be stated explicitly.}
{This might appear to be an incompatibility since the explicit
prohibition is missing from Fortran 2003 and 2008, and thus should
require an edit to the "compatibility" subclauses in clause 4.
However as it seems somewhat contradictory, it is argued that those
standards do not establish an unambiguous interpretation of the code
in question, so no compatibility issue arises.}
SUBMITTED BY: Van Snyder
HISTORY: 18-262r1 m217 Submitted
18-262r2 m217 Revised draft - Passed by J3 meeting
19-228 m220 Passed by J3 letter ballot #35
----------------------------------------------------------------------
----------------------------------------------------------------------
NUMBER: F18/004
TITLE: Program execution sequence with failed images
KEYWORDS: Program execution, Termination of execution, Failed image,
DEFECT TYPE: Erratum
STATUS: Passed by J3 letter ballot
QUESTION:
Consider execution of a program with more than one image, and some
image has failed (perhaps by execution of FAIL IMAGE, or perhaps by
some actual failure). Let us further suppose that all other images
have initiated normal termination.
According to 5.3.7 "Termination of execution", paragraph 1:
"Termination of execution of the program occurs
when all images have terminated execution."
This text is unchanged from Fortran 2008, which did not have failed
images.
As an image that has failed "has ceased participating in program
execution but has not terminated execution", it would seem that in
this situation, execution of the program has not terminated.
Should failed images cause execution of the program not to terminate?
ANSWER:
No, failed images have stopped participating in program execution and
therefore their existence should not prevent program termination.
That this definition is unchanged from Fortran 2008 is an oversight.
An edit is supplied to correct this.
EDIT to 18-007r1:
[38:8] 5.3.7 Termination of execution, p1,
After "when all images have terminated execution"
insert "or failed",
making the last sentence of the paragraph read
"Termination of execution of the program occurs when all images
have terminated execution or failed."
SUBMITTED BY: Malcolm Cohen
HISTORY: 19-129 m218 Submitted
19-129r1 m218 Revised draft - Passed by J3 meeting
19-228 m220 Passed as amended by J3 letter ballot #25
----------------------------------------------------------------------
----------------------------------------------------------------------
NUMBER: F18/005
TITLE: Does INPUT_UNIT really identify the same unit as *?
KEYWORDS: Connection, INPUT_UNIT
DEFECT TYPE: Interpretation
STATUS: Passed by J3 letter ballot
QUESTION:
According to 16.10.2.13 INPUT_UNIT [429:8-9],
"The value of the default integer scalar constant INPUT_UNIT
identifies the same processor-dependent external unit
preconnected for sequential formatted input as the one
identified by an asterisk in a READ statement;"
Consider the program:
PROGRAM input_unit_test
USE iso_fortran_env
CHARACTER(80) line
OPEN(input_unit,FILE='test.dat',ACTION='read')
READ(input_unit,'(a)') line
PRINT *,TRIM(line)
READ(*,'(a)') line
PRINT *,TRIM(line)
END PROGRAM
Furthermore, let us suppose the file test.dat contains the
following two lines:
dat line 1
dat line 2
and let us further suppose the file that was preconnected before the
OPEN statement contains the following single line:
inp line 1
Is the output of the program (1):
dat line 1
dat line 2
or is it (2):
dat line 1
inp line 1
?
The plain meaning of the words
"identifies the same processor-dependent external unit...
...as the one identified by an asterisk in a READ"
would seem to imply that (1) is expected, not (2); however, only
some Fortran processors produce output (1), while others have been
observed to produce output (2).
ANSWER:
Output (1) is correct. According to the quoted words, using
INPUT_UNIT in a READ statement must have the same effect as UNIT=*
(which is the same effect as not having a input/output control list).
It is common for unit 5 to be effectively preconnected to stdin, but
on some processors changing the connection of unit 5 (e.g. with an
OPEN statement) does not affect unit=*. On such a processor, the
value of INPUT_UNIT should not be equal to 5, but to whatever value,
possibly negative, that will continue to connect to unit=*.
EDIT to 18-007r1:
None.
SUBMITTED BY: Malcolm Cohen
HISTORY: 19-130 m218 Submitted
19-130r1 m218 Revised draft - Passed by J3 meeting
19-228 m220 Passed by J3 letter ballot #35
----------------------------------------------------------------------
----------------------------------------------------------------------
NUMBER: F18/006
TITLE: Connection of INPUT_UNIT on different images
KEYWORDS: Connection, INPUT_UNIT
DEFECT TYPE: Erratum
STATUS: Passed by J3 letter ballot
QUESTION:
According to 16.10.2.13 INPUT_UNIT [429:8-9],
"The value of the default integer scalar constant INPUT_UNIT
identifies the same processor-dependent external unit
preconnected for sequential formatted input as the one
identified by an asterisk in a READ statement;"
and according to 12.5.1 Referring to a file [217:10-11],
"In a READ statement, an io-unit that is an asterisk identifies
an external unit that is preconnected for sequential formatted
input on image 1 in the initial team only (12.6.4.3)."
This leaves unanswered the status of the i/o unit identified by
INPUT_UNIT on images other that 1. Plausible interpretations are:
(a) it is not preconnected on other images;
(b) it is preconnected, but to a processor-dependent file;
(c) it is preconnected, but it is not standard-conforming for a
program to use it;
(d) it is preconnected, but it raises an i/o error condition if a
program attempts to use it;
(e) attempting to use INPUT_UNIT in any way, including connecting it
to another file, is not conforming;
(f) INPUT_UNIT may be connected to another file, but it is still
processor-dependent whether it may be used;
(g) on an image other than image 1,
- it is processor-dependent whether it is preconnected,
- if it is preconnected,
* it is processor-dependent to what file,
* it is processor-dependent whether use is permitted,
- if it is subsequently connected, it is processor-dependent
whether it may be used.
Q1. What is the preconnection status of INPUT_UNIT on images other
than image one?
Q2. On an image other than image one, if INPUT_UNIT happens to be
preconnected, may it be used?
Q3. On an image other than image one, if INPUT_UNIT is connected to
a different file by an OPEN statement, may it be used?
Also, the definition text for INPUT_UNIT in 16.10.2.13 makes no
mention of any caveat, but implies it is preconnected on every image.
Perhaps this text could be clarified.
ANSWER:
A1. INPUT_UNIT (and thus the unit identified by an asterisk in a READ
statement) was not intended to be preconnected on images other
than image one in the initial team.
An edit is supplied to correct this omission.
A2. Moot.
A3. Yes.
EDITS to 18-007r1:
[217:11] 12.5.1 Referring to a file, p4,
After "on image 1 in the initial team only (12.6.4.3)"
insert "; it is not preconnected on any other image".
{Clarify preconnection state on images other than one.}
{Editor notes that "image 1" should be "image one".}
[429:9,10] 16.10.2.13 INPUT_UNIT, p1,
Delete "preconnected for sequential formatted input".
{This is a mere parenthetical remark which could confuse.}
After "input/output control list (12.6.4.3)." insert new sentence
"This unit is preconnected for sequential formatted input on
image one in the initial team only, and is not preconnected
on any other image."
{Make this match clause 12.}
SUBMITTED BY: Malcolm Cohen
HISTORY: 19-131 m218 Submitted
19-131r1 m218 Revised draft - Passed by J3 meeting
19-228 m220 Passed by J3 letter ballot #35
----------------------------------------------------------------------
----------------------------------------------------------------------
NUMBER: F18/008
TITLE: Contradictory assumed-rank requirements
KEYWORDS: Assumed rank
DEFECT TYPE: Erratum
STATUS: Passed by J3 letter ballot
QUESTION:
Paragraph 1 of subclause 8.5.8.7 (Assumed-rank entity) states that an
assumed-rank entity is a dummy data object ... or the associate name
of a RANK DEFAULT block in a SELECT RANK construct.
C837 requires an assumed-rank entity to be a dummy data object. It
does not permit an associate name of a RANK DEFAULT block in a SELECT
RANK construct to have assumed rank.
Is an associate name of a RANK DEFAULT block in a SELECT RANK
construct permitted to have assumed rank?
ANSWER:
Yes, the associate name of a RANK DEFAULT block may have assumed rank.
An edit is supplied to remove the contradiction.
EDIT to 18-007r1:
[101:13-14 C837 in 8.5.8.7 Assumed-rank entity]
At the end of C837, after "or VALUE attribute", insert
", or the associate name of a RANK DEFAULT block in a SELECT RANK
construct whose selector has assumed rank",
making the whole constraint read:
C837 An assumed-rank entity shall be a dummy data object that does not
have the CODIMENSION or VALUE attribute, or the associate name of
a RANK DEFAULT block in a SELECT RANK construct whose selector
has assumed rank.
SUBMITTED BY: Van Snyder
HISTORY: 19-119 m218 Submitted
19-119r1 m218 Revised draft - Passed by J3 meeting
19-228 m220 Passed by J3 letter ballot #35
----------------------------------------------------------------------
----------------------------------------------------------------------
NUMBER: F18/009
TITLE: Bad examples in IEEE_ARITHMETIC functions
KEYWORDS: IEEE_VALUE, IEEE_ARITHMETIC module, examples
DEFECT TYPE: Erratum
STATUS: Passed by J3 letter ballot
QUESTION:
In 17.11 the examples for IEEE_MAX_NUM, IEEE_MIN_NUM,
IEEE_QUIET_compare functions, and IEEE_SIGNALING_compare functions all
contain a call to IEEE_VALUE(IEEE_QUIET_NAN). IEEE_VALUE has two
non-optional arguments, not one. Should calls to IEEE_VALUE in each of
these examples have an additional X= argument?
ANSWER:
Yes, IEEE_VALUE has two non-optional arguments, X and CLASS.
The X argument was mistakenly omitted.
Edits are provided to fix these issues.
EDITS to 18-007r1:
[448:12] 17.11.17 IEEE_MAX_NUM p8
Change "IEEE_VALUE (IEEE_QUIET_NAN)" to
"IEEE_VALUE (1.0, IEEE_QUIET_NAN)"
[449:9] 17.11.19 IEEE_MIN_NUM p8
Change "IEEE_VALUE (IEEE_QUIET_NAN)" to
"IEEE_VALUE (1.0, IEEE_QUIET_NAN)"
[451:4] 17.11.24 IEEE_QUIET_EQ p7
Change "IEEE_VALUE (IEEE_QUIET_NAN)" to
"IEEE_VALUE (1.0, IEEE_QUIET_NAN)"
[451:18] 17.11.25 IEEE_QUIET_GE p7
Change "IEEE_VALUE (IEEE_QUIET_NAN)" to
"IEEE_VALUE (1.0, IEEE_QUIET_NAN)"
[451:32] 17.11.26 IEEE_QUIET_GT p7
Change "IEEE_VALUE (IEEE_QUIET_NAN)" to
"IEEE_VALUE (1.0, IEEE_QUIET_NAN)"
[452:10] 17.11.27 IEEE_QUIET_LE p7
Change "IEEE_VALUE (IEEE_QUIET_NAN)" to
"IEEE_VALUE (1.0, IEEE_QUIET_NAN)"
[452:24] 17.11.28 IEEE_QUIET_LT p7
Change "IEEE_VALUE (IEEE_QUIET_NAN)" to
"IEEE_VALUE (1.0, IEEE_QUIET_NAN)"
[452:38] 17.11.29 IEEE_QUIET_NE p7
Change "IEEE_VALUE (IEEE_QUIET_NAN)" to
"IEEE_VALUE (1.0, IEEE_QUIET_NAN)"
[457:37] 17.11.41 IEEE_SIGNALING_EQ p7
Change "IEEE_VALUE (IEEE_QUIET_NAN)" to
"IEEE_VALUE (1.0, IEEE_QUIET_NAN)"
[458:13] 17.11.42 IEEE_SIGNALING_GE p7
Change "IEEE_VALUE (IEEE_QUIET_NAN)" to
"IEEE_VALUE (1.0, IEEE_QUIET_NAN)"
[458:27] 17.11.43 IEEE_SIGNALING_GT p7
Change "IEEE_VALUE (IEEE_QUIET_NAN)" to
"IEEE_VALUE (1.0, IEEE_QUIET_NAN)"
[459:4] 17.11.44 IEEE_SIGNALING_LE p7
Change "IEEE_VALUE (IEEE_QUIET_NAN)" to
"IEEE_VALUE (1.0, IEEE_QUIET_NAN)"
[459:18] 17.11.45 IEEE_SIGNALING_LT p7
Change "IEEE_VALUE (IEEE_QUIET_NAN)" to
"IEEE_VALUE (1.0, IEEE_QUIET_NAN)"
[459:32] 17.11.46 IEEE_SIGNALING_NE p7
Change "IEEE_VALUE (IEEE_QUIET_NAN)" to
"IEEE_VALUE (1.0, IEEE_QUIET_NAN)"
SUBMITTED BY: Jon Steidel
HISTORY: 19-124 m218 Submitted - Passed by J3 meeting
19-228 m220 Passed by J3 letter ballot #35
----------------------------------------------------------------------
----------------------------------------------------------------------
NUMBER: F18/010
TITLE: Categories of pure procedures
KEYWORDS: pure
DEFECT TYPE: Erratum
STATUS: Passed by J3 letter ballot
QUESTION:
Subclause 15.7 Pure procedures begins with a list of categories of
pure procedures. The list does not include procedure pointers or
type-bound procedures. Dummy procedures are included in the list, and
so dummy procedure pointers are allowed, but other procedure pointers
are not.
Q1. Can procedure pointers that are not dummy procedures be pure?
Q2: Can type-bound procedures be pure?
ANSWER:
A1. Procedure pointers that are not dummy procedures are allowed to
be pure. The absence of procedure pointers in the list in
Subclause 15.7 is an oversight. An edit to correct the oversight
is provided.
A2. Type-bound procedures that are bound to pure procedures are pure.
The absence of type-bound procedures in Subclause 15.7 is an
oversight. An edit to correct the oversight is provided.
EDITS to 18-007r1:
[324:1, 15.7 "Pure procedures" p1]
Replace
"specified to be PURE, or"
with
"specified to be PURE,
* a procedure pointer that has been specified to be PURE,
* a type-bound procedure that is bound to a pure procedure, or"
{ Add missing entries to the list in Subclause 15.7. }
SUBMITTED BY: Robert Corbett
HISTORY: 19-151 m218 Submitted - Passed by J3 meeting
19-228 m220 Passed by J3 letter ballot #35
----------------------------------------------------------------------
----------------------------------------------------------------------
NUMBER: F18/011
TITLE: Categories of elemental procedures
KEYWORDS: elemental
DEFECT TYPE: Erratum
STATUS: Passed by J3 letter ballot
QUESTION:
The list of categories of elemental procedures at the start of
Subclause 15.8 "Elemental procedures" [325:11-12] is incomplete.
Procedures that are defined to be elemental in intrinsic modules
are not included. Type-bound procedures are not included.
Dummy procedures and procedure pointers are not included, but
there is evidence that those omissions were intentional.
The standard intrinsic modules specify several procedures to be
elemental. The omission of module procedures declared in intrinsic
modules from the list in Subclause 15.8 creates a contradiction.
Subclause 7.5.6.2 [80:5-8] and Subclause 7.5.7.3 [82:16] both
assume that type-bound procedures may be elemental.
Nonintrinsic elemental procedures cannot be used as actual arguments
[301: 29, 15.5.1 "Syntax of a procedure reference" p1]. Elemental
procedures specified in the standard intrinsic modules are generic,
and so they cannot be passed as actual arguments. Elemental intrinsic
procedures can be passed as actual arguments [309: 2-5, 15.5.2.9
"Actual arguments associated with dummy procedure entities" p1], but
the text cited indicates that dummy procedures cannot be elemental.
Procedure pointers pose a bit of a problem. A nonintrinsic elemental
procedure cannot be the target of a pointer assignment [165:34,
10.2.2.2 "Syntax of the pointer assignment statement" ]. However,
Subclause 10.2.2.4 "Pointer procedure assignment" paragraph 3 states
If the pointer object has an explicit interface, its
characteristics shall be the same as the pointer target except
that the pointer target may be pure even if the pointer object
is not pure and the pointer target may be an elemental intrinsic
procedure even if the pointer object is not elemental.
The final phrase suggests that a pointer object might be elemental,
but it does not say that it can be elemental.
Q1. Is a procedure in an intrinsic module that is specified
to be elemental an elemental procedure?
Q2. Can a type-bound procedure be elemental?
Q3. Can a dummy procedure be specified to be elemental?
Q4. Can a procedure pointer be specified to be elemental?
ANSWER:
A1. Procedures in intrinsic modules that are specified to be elemental
are elemental. An edit is provided to correct the omission in
Subclause 15.8.
A2. A type-bound procedure that is bound to an elemental
procedure is elemental. An edit is provided to correct
the omission in Subclause 15.8.
A3. A dummy procedure cannot be specified to be elemental.
An edit is provided to make this restriction explicit.
A4. A procedure pointer cannot be specified to be elemental.
An edit is provided to make this restriction explicit.
The edits provided are intended to make the impact on the existing
standard small. More extensive changes are probably desirable, and
could be made in a revision of the standard. In particular, the
restrictions on dummy arguments and procedure pointers could be made
constraints.
EDITS to 18-007r1:
[167:8] 10.2.4.4 Procedure pointer assignment, p3, Replace
"elemental intrinsic procedure even if the pointer object
is not elemental."
with
"elemental intrinsic procedure, even though the pointer
object is not elemental."
{ Remove the suggestion that a procedure pointer might
be elemental.}
[325:11-12] 15.8.1 Elemental procedure declaration and interface, p1,
Replace the sentence
"An elemental procedure is ... an elemental subprogram."
with
"An elemental procedure is
* an elemental intrinsic procedure (16.1),
* a module procedure in an intrinsic module, if it is
specified to be elemental,
* a procedure that is defined by an elemental subprogram, or
* a type-bound procedure that is bound to an elemental
procedure."
and insert a new paragraph following it:
"A dummy procedure or procedure pointer shall not be
specified to be ELEMENTAL."
{ Add missing items to the list in Subclause 15.8. Add a
missing restriction to Subclause 15.8. }
SUBMITTED BY: Robert Corbett
HISTORY: 19-153 m218 Submitted
19-153r1 m218 Amended - Passed by J3 meeting
19-228 m220 Passed by J3 letter ballot #35
----------------------------------------------------------------------
----------------------------------------------------------------------
NUMBER: F18/012
TITLE: Internal procedure in a generic interface
KEYWORDS: Internal procedure, Generic interface
DEFECT TYPE: Clarification
STATUS: Passed by J3 letter ballot
QUESTION:
In Fortran 2003, an internal subprogram was not allowed to define a
specific procedure for a generic identifier:
Fortran 2003 [285:14-15]
C1207 (R1206) A <procedure-name> shall have an explicit interface and
shall refer to an accessible procedure pointer, external
procedure, dummy procedure, or module procedure.
Paper 08-178 proposed the new feature of permitting an internal
procedure in this context, and this was included in Fortran 2008:
[Fortran 2008 281:8]
C1207 (R1206) A <procedure-name> shall be a nonintrinsic procedure
that has an explicit interface.
However, this new feature was not mentioned in the Introduction of
Fortran 2008, nor is it mentioned in Annex C.1 of Fortran 2018
(which lists Fortran 2008 features not originally mentioned in its
Introduction).
Should this be mentioned in Annex C.1?
ANSWER:
Yes, this new feature should be mentioned in Annex C.1.
An edit is provided.
EDIT:
[528:22+] C.1 Fortran 2008 features not mentioned in its
Introduction, p1,
Insert an item at the end of the bullet list:
"- An internal procedure name can appear in a
<procedure-stmt> in a generic interface block."
SUBMITTED BY: Van Snyder
HISTORY: 19-179 m219 Submitted - Passed by J3 meeting
19-228 m220 Passed by J3 letter ballot #35
----------------------------------------------------------------------
----------------------------------------------------------------------
NUMBER: F18/013
TITLE: TEAM_NUMBER arguments and intrinsic function are ambiguous
KEYWORDS: NUM_IMAGES, IMAGE_INDEX, TEAM_NUMBER, teams
DEFECT TYPE: Erratum
STATUS: Passed by J3 letter ballot
QUESTION:
Consider
PROGRAM p
n = NUM_IMAGES()
n1 = MERGE(1,2,THIS_IMAGE()<2)
n2 = MERGE(1,3,THIS_IMAGE()<3)
FORM TEAM(n1,x)
FORM TEAM(n2,y)
IF (n1==1) THEN
CHANGE TEAM (x)
PRINT *,NUM_IMAGES(TEAM_NUMBER=1) !(A)
PRINT *,NUM_IMAGES(TEAM_NUMBER=3) !(B)
END TEAM
END IF
END PROGRAM
According to 16.9.145 NUM_IMAGES, the TEAM_NUMBER argument
"shall identify the initial team or a team whose parent is the
same as that of the current team".
However, at (A), there are two teams with team number 1 and the same
parent, one created by the FORM TEAM with "n1", the other created by
the FORM TEAM with "n2".
At (B), there is only one team with team number 3 and the same parent
as the current team, however, it is not a "sibling" team in that it
was not created by the same FORM TEAM statement.
Referring to the definition of the term "team number" at 3.145.4:
"-1 which identifies the initial team, or positive integer that
identifies a team within its parent team"
which has the same flaw in that there could be multiple teams within
the parent team that have that number.
Q1. Was TEAM_NUMBER in NUM_IMAGES, and the "team number" definition,
intended to limit the identification to teams created by
corresponding FORM TEAM statement executions?
Q2. The TEAM_NUMBER argument of IMAGE_INDEX suffers from similar
wording. Was this also intended to be limited to "sibling" teams?
ANSWER:
Yes, this is the intention. Edits are provided.
The edits use the terminology "corresponding" executions, as execution
on more than one image can hardly be the "same" execution.
The edits also use the term "sibling teams". As sibling teams are
always created as a group, and really only have meaning when there are
more than one, the plural form is probably most appropriate.
EDITS:
[20:27+] Terms and definitions:
Insert after the definition of "parent team"
"3.145.3+
sibling teams
teams created by a single set of corresponding executions of the
FORM TEAM statement (11.6.9)"
[20:30] 3.145.4 team number, definition, change
"within its parent team" -> "among its sibling teams"
making the definition read
"-1 which identifies the initial team, or a positive integer that
identifies a team among its sibling teams (5.3.4)
[36:23] 5.3.4 Program execution, para 2, final sentence
Replace "Within its parent team,"
with "Among its sibling teams,"
making the whole sentence read
"Among its sibling teams, each team is identified by its
team_number; this is the integer value that was specified in the
FORM TEAM statement."
{This is just waffle, no need to index "sibling teams".}
[131:18-19] In 9.6 Image selectors, p3 second sentence
Replace "one of the teams that were formed by execution of
the FORM TEAM statement for"
with "a sibling team of"
making the whole sentence read
"If a TEAM_NUMBER= specifier appears in an image-selector and the
current team is not the initial team, the value of scalar-int-expr
shall be equal to the value of a team number for a sibling team of
the current team, and the team of the image selector is that team;
the object shall be an established coarray in an ancestor team of
the current team, or an associating entity of the CHANGE TEAM
construct."
[204:35] 11.6.9 FORM TEAM statement, p1,
change "creates new teams"
to "creates a set of sibling teams"
and index "sibling teams" here.
This makes that whole paragraph read:
"The FORM TEAM statement creates a set of sibling teams whose
parent team is the current team."
[380:12-13] In 16.9.97 IMAGE_INDEX, p3 TEAM_NUMBER
Change
"team whose parent is the same as that of the current team"
to
"sibling team of the current team"
and index "sibling teams" here.
making the whole argument read:
"TEAM_NUMBER shall be an integer scalar. It shall identify the
initial team or a sibling team of the current team."
[401:24-25] 16.9.145 NUM_IMAGES, p3 Arguments, TEAM_NUMBER argument,
Change
"team whose parent is the same as that of the current team"
to
"sibling team of the current team"
and index "sibling teams" here.
This makes that whole argument read:
"TEAM_NUMBER shall be an integer scalar. It shall identify the
initial team or a sibling team of the current team."
[421:9]16.9.189 TEAM_NUMBER([TEAM]), p5 Result Value,
Change "within its parent team"
to "among its sibling teams",
and index "sibling teams" here.
This makes that whole paragraph read:
"The result has the value -1 if the specified team is the initial
team; otherwise, the result value is equal to the positive integer
that identifies the specified team among its sibling teams."
SUBMITTED BY: Malcolm Cohen, Jon Steidel, and John Reid
HISTORY: 19-190 m219 Submitted
19-190r1 m219 Merged with 19-178 - Passed by J3 meeting
19-228 m220 Passed as amended by J3 letter ballot #35
----------------------------------------------------------------------
----------------------------------------------------------------------
NUMBER: F18/014
TITLE: Type of OPERATION arguments to the REDUCE intrinsic
KEYWORDS: REDUCE, OPERATION, polymorphic, type
DEFECT TYPE: Erratum
STATUS: Passed by J3 letter ballot
QUESTION:
Section 16.9.161 REDUCE p3 describes the arguments to the intrinsic
subroutine CO_REDUCE.
The description of the ARRAY argument states:
"ARRAY shall be an array of any type."
It describes the OPERATION argument as:
"OPERATION shall be a pure function with exactly two arguments; each
argument shall be a scalar, nonallocatable, nonpointer, nonoptional
dummy data object with the same type and type parameters as ARRAY.
If one argument has the ASYNCHRONUS, TARGET, or VALUE attribute, the
other shall have that attribute. Its result shall be a non-
polymorphic scalar and have the same type and type parameters as
ARRAY. OPERATION should implement a mathematically associative
operation. It need not be commutative."
The function result of OPERATION cannot be polymorphic. The arguments
to OPERATION must have the same type as its result, and thus cannot be
polymorphic. However, ARRAY can be polymorphic. This means the dynamic
type of ARRAY must be the same type as the arguments and result of
OPERATION. This seems like an unfortunate requirement.
Was it intended that the dynamic type of ARRAY be required to match
the type and type parameters of the arguments of OPERATION?
ANSWER:
No, this requirement was not intended. Edits are provided to correct
the problem.
EDITS:
[408:36] change "type and type parameters"
to "declared type and type parameters"
[408:39] change "type and type parameters"
to "declared type and type parameters"
so that the description of OPERATION reads:
"shall be a pure function with exactly two arguments; each argument
shall be a scalar, nonallocatable, nonpointer, nonoptional dummy
data object with the same declared type and type parameters as
ARRAY. If one argument has the ASYNCHRONOUS, TARGET, or VALUE
attribute, the other shall have the attribute. Its result shall be
a non-polymorphic scalar and have the same declared type and type
parameters as ARRAY. OPERATION should implement a mathematically
associative operation. It need not be commutative."
[409:5] change "type and type parameters"
to "declared type and type parameters"
so that the first sentence of Result Characteristics reads:
"The result is of the same declared type and type parameters as
ARRAY."
SUBMITTED BY: Jon Steidel
HISTORY: 19-192 m219 Submitted
19-192r1 m219 Revised draft - Passed by J3 meeting
19-228 m220 Passed by J3 letter ballot #35
----------------------------------------------------------------------
----------------------------------------------------------------------
NUMBER: F18/015
TITLE: Example in C.6.8 is wrong
KEYWORDS: failed images
DEFECT TYPE: Erratum
STATUS: Passed by J3 letter ballot
The example code for failed images in C.6.8 raises several issues about
its correctness.
QUESTION:
Q1.
A: In the example in C.6.8, the assignments
me[k] = failures(i)
id[k] = 1
are made by image 1 and the assignments
me = THIS_IMAGE ()
id = MERGE (1, 2, me<=images_used)
are made by image k in unordered segments. Was this intended?
B: In the example in C.6.8, the assignment
me[k] = failures(i)
is made by image 1 and me[k] is referenced on other images in
the FORM TEAM statement in unordered segments. Was this
intended?
Q2.
Suppose the program in C.6.8 is executed by 11 images, so 1 is
intended to be a spare. If image 9 in the initial team fails
immediately before it executes the first FORM TEAM statement, then
image 10 in the initial team, which executes FORM TEAM with a
team-number == 1 and NEW_INDEX == 10 (== me), will have specified
a NEW_INDEX= value greater than the number of images in the new
team. Should there be a test for this in the code?
Q3.
A: If a replacement image has failed, its image index will be the
value of an element of the array failures, a replacement for it
will be found, and the replacement will be placed in team 1. Was
this intended?
B: The value of images_used increases each time the setup loop is
executed. However, the array failures will contain the image
indices of all the failed images and allocate all of them fresh
replacements. Was this intended?
ANSWER:
1-A: No. An image control statement that provides segment ordering is
needed.
1-B: No.
2: This is quite a low-probability event, so exiting with the error
condition seems appropriate.
3-A: No.
3_B: No. It was intended to allocate replacements only for the newly
failed images.
Furthermore, the example contains more errors than in the list above.
Therefore an edit is provided that replaces the entire example with
a complete rewrite, involving correction of additional errors, a
better choice of names, and more comments.
Some of the noteworthy additional changes are:
- declarations separated out and many comments added or changed;
- rename ME to LOCAL_INDEX and ID to TEAM_NUMBER;
- code added to calculate the local indices of team 2;
- THEN keyword added to ELSE IF (done) statement.
EDITS to 18-007r1:
[543:42-545:17] C.6.8 Example involving failed images,
Replace the entire example with the code below.
Note that many lines and comments are broken to keep
them within 70 columns, these should be joined up or
reformatted in the actual standard.
"
PROGRAM possibly_recoverable_simulation
USE, INTRINSIC :: ISO_FORTRAN_ENV, ONLY:TEAM_TYPE, STAT_FAILED_IMAGE
IMPLICIT NONE
INTEGER, ALLOCATABLE :: failures (:) ! Indices of the failed images.
INTEGER, ALLOCATABLE :: old_failures(:) ! Previous failures.
INTEGER, ALLOCATABLE :: map(:) ! For each spare image k in use,
! map(k) holds the index of the failed image it replaces.
INTEGER :: images_spare ! No. spare images.
! Not altered in main loop.
INTEGER :: images_used ! Max index of image in use.
INTEGER :: failed ! Index of a failed image.
INTEGER :: i, j, k ! Temporaries
INTEGER :: status ! stat= value
INTEGER :: team_number [*] ! 1 if in working team; 2 otherwise.
INTEGER :: local_index [*] ! Index of the image in the team.
TYPE (TEAM_TYPE) :: simulation_team
LOGICAL :: read_checkpoint ! If read_checkpoint true on
! entering simulation_procedure, go back to previous check point.
LOGICAL :: done [*] ! True if computation finished on the image.
! Keep 1% spare images if we have a lot, just 1 if 10-199 images,
! 0 if <10.
images_spare = MAX(NUM_IMAGES()/100,0,MIN(NUM_IMAGES()-10,1))
images_used = NUM_IMAGES () - images_spare
ALLOCATE ( old_failures(0), map(images_used+1:NUM_IMAGES()) )
read_checkpoint = .FALSE. ! Initial startup, not from checkpoint.
outer : DO
local_index = THIS_IMAGE ()
team_number = MERGE (1, 2, local_index<=images_used)
SYNC ALL (STAT = status)
IF (status/=0 .AND. status/=STAT_FAILED_IMAGE) EXIT outer
IF (IMAGE_STATUS (1) == STAT_FAILED_IMAGE) &
ERROR STOP "cannot recover"
IF (THIS_IMAGE () == 1) THEN
! For each newly failed image in team 1, move into team 1 a
! non-failed image of team 2.
failures = FAILED_IMAGES () ! Note that the values
! returned by FAILED_IMAGES increase monotonically.
k = images_used
j = 1
DO i = 1, SIZE (failures)
IF (failures(i) > images_used) EXIT ! This failed image and
! all further failed images are in team 2 and do not matter.
failed = failures(i)
! Check whether this is an old failed image.
IF (j <= SIZE (old_failures)) THEN
IF (failed == old_failures(j)) THEN
j = j+1
CYCLE ! No action needed for old failed image.
END IF
END IF
! Allow for the failed image being a replacement image.
IF (failed > NUM_IMAGES()-images_spare) failed = map(failed)
! Seek a non-failed image
DO k = k+1, NUM_IMAGES ()
IF (IMAGE_STATUS (k) == 0) EXIT
END DO
IF (k > NUM_IMAGES ()) ERROR STOP "cannot recover"
local_index [k] = failed
team_number [k] = 1
map(k) = failed
END DO
old_failures = failures
images_used = k
! Find the local indices of team 2
j = 0
DO k = k+1, NUM_IMAGES ()
IF (IMAGE_STATUS (k) == 0) THEN
j = j+1
local_index[k] = j
END IF
END DO
END IF
SYNC ALL (STAT = status)
IF (status/=0 .AND. status/=STAT_FAILED_IMAGE) EXIT outer
!
! Set up a simulation team of constant size.
! Team 2 is the set of spares, so does not participate.
FORM TEAM (team_number, simulation_team, NEW_INDEX=local_index, &
STAT=status)
IF (status/=0 .AND. status/=STAT_FAILED_IMAGE) EXIT outer
simulation : CHANGE TEAM (simulation_team, STAT=status)
IF (status == STAT_FAILED_IMAGE) EXIT simulation
IF (team_number == 1) THEN
iter : DO
CALL simulation_procedure (read_checkpoint, status, done)
! The simulation_procedure:
! - sets up and performs some part of the simulation;
! - resets to the last checkpoint if requested;
! - sets status from its internal synchronizations;
! - sets done to .TRUE. when the simulation has completed.
IF (status == STAT_FAILED_IMAGE) THEN
read_checkpoint = .TRUE.
EXIT simulation
ELSE IF (done) THEN
EXIT iter
END IF
read_checkpoint = .FALSE.
END DO iter
END IF
END TEAM (STAT=status) simulation
SYNC ALL (STAT=status)
IF (THIS_IMAGE () > images_used) done = done[1]
IF (done) EXIT outer
END DO outer
IF (status/=0 .AND. status/=STAT_FAILED_IMAGE) &
PRINT *,'Unexpected failure',status
END PROGRAM possibly_recoverable_simulation
"
SUBMITTED BY: John Reid
HISTORY: 19-182 m219 Submitted
19-182r3 m219 Revised draft - Passed by J3 meeting
19-228 m220 Failed J3 letter ballot #35
20-105 m221 Revised answer - Passed by J3 meeting
20-132 m222 Passed as amended by J3 letter ballot #36
----------------------------------------------------------------------
----------------------------------------------------------------------
NUMBER: F18/016
TITLE: Host association changes in Fortran 2018
KEYWORDS: Host association
DEFECT TYPE: Erratum
STATUS: Passed by J3 letter ballot
QUESTION:
The default semantics for accessing entities by host association from
an interface body appear to be different in Fortran 2018 than in
Fortran 2008.
Problem 1:
In Fortran 2008, an interface body that is not a module procedure
interface body cannot access entities in its host by host association
unless an IMPORT statement is present in the interface body. The same
rule applies by default in Fortran 2018 if the interface body is for
an external or dummy procedure, but not if the interface body is for
an abstract interface or a procedure pointer that is not a dummy
procedure pointer (see 8.8 "IMPORT statement" [117:17-19]).
For example, in
DOUBLE PRECISION X
ABSTRACT INTERFACE
SUBROUTINE SUB(A)
REAL(KIND(X)) A
END SUBROUTINE
END INTERFACE
Fortran 2008 specifies that X is default REAL, and that therefore so
is argument A, but Fortran 2018 specifies that X is accessed by host
association and so argument A is double precision.
Problem 2:
The Fortran 2008 standard specified that a submodule has access to
host entities, but the Fortran 2018 standard does not specify any
default host association semantics for a submodule (it specifies
IMPORT semantics only for nested scoping units (see 8.8 "IMPORT
statement" [117:23-26]). That makes submodules using host association
not conforming.
For example, in
MODULE mod
INTERFACE
MODULE SUBROUTINE S
END SUBROUTINE
END INTERFACE
INTEGER,PARAMETER :: WP = KIND(0.0)
END MODULE
SUBMODULE (mod) submod
REAL(WP) X
END SUBMODULE
the submodule references WP by host association in Fortran 2008, but
Fortran 2018 does not specify any semantics and so the whole thing is
not conforming.
Problem 3:
The Fortran 2008 standard specified that generic identifiers were
accessible by host association, but the Fortran 2018 standard specifies
that host association is for named entities.
For example, in
INTERFACE OPERATOR(.plus.)
PROCEDURE plusfun
END INTERFACE
...
CONTAINS
SUBROUTINE SUB(a,b,c)
...
c = a.plus.b
Fortran 2018 would not permit access to the user-defined operator.
Problem 4:
The Fortran 2018 standard specifies that BLOCK constructs access named
entities in their hosts by host association. This makes no sense
because BLOCK constructs already have access to entities in their
hosts through inclusive scoping.
Were these changes intended?
ANSWER:
No, none of these changes were intended.
Edits are provided to restore the semantics specified in the Fortran
2008 standard.
EDITS to 18-007r1:
[117:18-19] 8.8 IMPORT statement, p2, second sentence,
Replace "interface body for an ... procedure."
with
"interface body that is not a module procedure
interface body."
making the sentence read
"This is the default for an interface body that is not
a module procedure interface body."
[117:25-26] 8.8 IMPORT statement, p4, second sentence,
Change "for a nested scoping unit ... procedure"
to "for a derived-type definition, internal subprogram,
module procedure interface body, module subprogram, or
submodule"
making the sentence read
"This is the default for a derived-type definition,
internal subprogram, module procedure interface body,
module subprogram, or submodule."
[502:7] 19.5.1.4 "Host association", p1, first sentence
Change "nested scoping unit"
to "derived-type definition, interface body, internal
subprogram, module subprogram, or submodule",
Delete "named",
Making the sentence read
"A derived-type definition, interface body, internal
subprogram, module subprogram, or submodule has access to
entities from its host as specified in 8.8."
SUBMITTED BY: Robert Corbett
HISTORY: 19-257 m220 F18/016 Submitted
19-257r1 m220 Revised draft - Passed by J3 meeting
20-132 m222 Passed by J3 letter ballot #36
----------------------------------------------------------------------
----------------------------------------------------------------------
NUMBER: F18/017
TITLE: Final subroutine invocation order
KEYWORDS: FINAL ALLOCATABLE
DEFECT TYPE: Erratum
STATUS: Passed by J3 letter ballot
QUESTION:
Consider
Module m
Type base
Contains
Final basef
End Type
Type other
Contains
Final otherf
End Type
Type,Extends(base) :: t
Type(other),Allocatable :: comp
Contains
Final tf
End Type
Contains
Subroutine basef(a)
Type(base),Intent(InOut) :: a
Print *,'basef'
End Subroutine
Subroutine otherf(b)
Type(other),Intent(InOut) :: b
Print *,'otherf'
End Subroutine
Subroutine tf(c)
Type(t),Intent(InOut) :: c
Print *,'tf'
End Subroutine
End Module
Program test
Use m
Call sub
Contains
Subroutine sub
Type(t) x
Allocate(x%comp)
End Subroutine
End Program
When the subroutine is executed, it will finalize X on exit,
so what is the expected output?
Finalization of X occurs before auto-deallocation of X%COMP;
this follows from 9.7.3.2 paragraph 9.
According to 7.5.6.2, in sequence
(1) the object's final procedure is invoked, i.e. TF is called,
(2) finalizable components are finalized, i.e. OTHERF is called,
(3) the parent is finalized, i.e. BASEF is called.
And according to 7.5.6.3, deallocating X%COMP finalizes it,
and so
(4) OTHERF is called.
I.e. the output is
TF
OTHERF
BASEF
OTHERF
However, this violates the principle that you only finalize something
once.
Q1. Is X%COMP actually finalized twice?
It could be argued that "finalizing X before deallocating X%COMP"
only puts an order on invocation of TF, and in particular, finalizing
the parent pseudo-component need not precede the deallocation. But
this would still invoke OTHERF twice.
Q3. Is the auto-deallocation of an allocatable component required to
follow the finalization of other components and the parent
pseudo-component?
Now consider the case where X%COMP is not allocated (i.e. delete the
ALLOCATE statement). According to 7.5.6.2, it should invoke
(1) TF on X
(2) OTHERF on X%COMP
(3) BASEF on X%BASE
however, as X%COMP is unallocated, the invocation in step (2) does
not conform to the procedure reference requirements, i.e. the program
is not conforming.
Q2. Is X%COMP required to be allocated when X is finalized?
DISCUSSION:
An object is only finalized in situations listed in 7.5.6.3.
Every such situation would also unconditionally deallocate any
allocatable component, and if that component were finalizable,
such deallocation would also unconditionally finalize the
component (* except for intrinsic assignment, where a previous
interpretation added an exclusion).
Therefore it seems to be broken to finalize any allocatable component
during finalization of the object it is contained in, as either it
will be non-conforming, or will be finalized twice (* except for the
previously-added exception).
The design where allocatable entities are finalized at the time of
deallocation would seem to be simpler, easier to understand, and less
buggy.
Perhaps the finalization of allocatable components in 7.5.6.2 step
(2) should be removed, and the exclusion for intrinsic assignment for
deallocation-finalization should also be removed?
ANSWER:
A1. No object should be finalized twice.
A2. No, a finalizable allocatable component should not be required to
be allocated when its containing object is finalized.
The inclusion of allocatable components in 7.5.6.2 step (2) is an
error in the standard, and the intrinsic assignment exception for
finalization on deallocation is likewise an error.
Edits are provided to correct these errors.
A3. An allocatable component should be able to be finalized as soon
as the object's final subroutine returns, i.e. there should be no
requirement on the processor to produce a particular invocation
order here.
The ambiguity in whether component deallocation and component
finalization should be ordered is inadvertent. An edit is provided
to remove any implication that these need to have a specific order.
FURTHER ELUCIDATION:
Finalization ordering is a partial ordering. When final subroutines
will be executed for a type (TFIN), an allocated allocatable component
thereof (AFIN), an ordinary (viz nonallocatable nonpointer) component
thereof (OFIN), and the type's parent type (PFIN), the orderings are:
TFIN<AFIN
TFIN<OFIN<PFINAL
Note there is no ordering between AFIN and OFIN, and no ordering
between AFIN and PFIN. Thus, after applying the edits below to the
standard, the following execution orders are valid:
TFIN, AFIN, OFIN, PFIN
TFIN, OFIN, AFIN, PFIN
TFIN, OFIN, PFIN, AFIN
EDITS to 18-007r1:
[80:9] 7.5.6.2 The finalization process, p1, item (2),
"All finalizable" -> "All nonallocatable finalizable".
{Remove redundant finalization.}
[80:22] 7.5.6.3 When finalization occurs, p2,
After
"unless it is the variable in an intrinsic assignment statement"
Delete "or a subobject thereof".
{Remove allocatable component exclusion in intrinsic assignment.}
[137:28] 9.7.3.2 Deallocation of allocatable variables, p9,
Change "that object is finalized"
To "any final subroutine for that object is executed",
Making the whole paragraph read
"If an allocatable component is a subobject of a finalizable
object, any final subroutine for that object is executed before
the component is automatically deallocated."
SUBMITTED BY: Malcolm Cohen
HISTORY: 20-117 m221 F18/017 Submitted - Passed by J3 meeting
20-132 m222 Passed as amended by J3 letter ballot
----------------------------------------------------------------------
----------------------------------------------------------------------
NUMBER: F18/018
TITLE: Public namelist and private variable
KEYWORDS: NAMELIST PUBLIC PRIVATE
DEFECT TYPE: Clarification
STATUS: Passed by J3 letter ballot
QUESTION:
Consider
Module m1
Real,Public :: x
End Module
Module m2
Use m1
Private x
Namelist/nml/x
End Module
On the face of it, module M2 appears to violate
C8105 (R868) A namelist-group-object shall not have the PRIVATE
attribute if the namelist-group-name has the PUBLIC attribute.
as the local X indeed has the PRIVATE attribute. On the other hand,
it is just a local name for the remote X which is PUBLIC, which
raises doubts.
Comment: This seems to be a very old constraint dating back to when
the standard was much more restrictive about such things.
It is not clear why this should be disallowed.
Even if X were a local variable of M2, it is not clear what
purpose this constraint serves.
A quick compiler survey revealed that most but not all compilers
think that it is where the variable is defined that matters, i.e.
many accept the example code.
Q1. Should PRIVATE local variables really be prohibited from a PUBLIC
namelist?
If the answer to Q1 is yes,
Q2. Is it PRIVATE on the local name that matters, or PRIVATE on the
variable where it is defined?
COMMENT:
A NAMELIST statement can contain several namelist-group-names, so it
is also somewhat ambiguous as to which namelist-group-objects this
constraint applies to.
ANSWER:
A1. Yes. Although it would be reasonable to lift this restriction in
a future standard, it is a deliberate restriction in this standard.
A2. It is whether the local name has the PRIVATE attribute that
matters, not where the variable is declared.
An edit is provided.
EDIT to 18-007r1:
[119:8-9] 8.9 NAMELIST statement, C8105,
After "PRIVATE attribute" insert "in the local scope",
and change "the namelist-group-name" to "its namelist-group-name",
making the whole constraint read
"C8105 (R868) A namelist-group-object shall not have the PRIVATE
attribute in the local scope if its namelist-group-name
has the PUBLIC attribute."
SUBMITTED BY: Malcolm Cohen
HISTORY: 20-127 m221 F18/018 Submitted
20-127r1 m221 Passed by J3 meeting
20-132 m222 Passed as amended by J3 letter ballot #36
----------------------------------------------------------------------
More information about the J3
mailing list