@@ -6,23 +6,21 @@ Date: 19 November 2019
6
6
Proposal for Fortran Standard: 202y
7
7
8
8
9
- Introduction
10
- ============
9
+ 1. Introduction
11
10
12
- According to the current standard, a WRITE statement can write a namelist
13
- file that does not conform to the namelist specification. This happens
14
- when the namelist group contains a character array and the DELIM specifier
15
- has a value of NONE. In particular, this is the default behavior of a
16
- WRITE statement whose input is a namelist.
11
+ According to the current standard, a WRITE statement can write a
12
+ namelist file that does not conform to the namelist specification. This
13
+ happens when the namelist group contains a character array and the DELIM
14
+ specifier has a value of NONE. In particular, this is the default
15
+ behavior of a WRITE statement whose input is a namelist.
17
16
18
- Our proposal is to require delimiters when using WRITE to write a namelist
19
- to a file, by either requiring a value of DELIM which is
17
+ Our proposal is to require delimiters when using WRITE to write a
18
+ namelist to a file, by either requiring a value of DELIM which is
20
19
namelist-compliant, or by overriding a value of NONE when the input is a
21
20
namelist.
22
21
23
22
24
- Motivation
25
- ==========
23
+ 2. Motivation
26
24
27
25
The namelist format is described in section 13.11 of the standard, and
28
26
13.11.3.3p7 requires that character arrays in namelist groups must be
@@ -34,47 +32,46 @@ delimited with single or double quotes.
34
32
delimited by apostrophes or quotes.
35
33
36
34
Any namelist whose character arrays are non-delimited is non-conformant.
37
- Any parsing of this output is therefore considered to be unformatted, and
38
- the interpretation is at the discretion of the interpreter.
35
+ Any parsing of this output is therefore considered to be unformatted,
36
+ and the interpretation is at the discretion of the interpreter.
39
37
40
38
Without delimiters, many character arrays become unparseable. If a
41
- character array contains any lexical tokens, then it is likely that
42
- non-delimited values will be misinterpreted as part of the namelist object
43
- structure. For example, any character array containing a slash ``/`` may
44
- abruptly terminate the current namelist group. Note 13.36 also recognizes
45
- the challenges of distinguishing between non-delimited character arrays and
46
- object names.
39
+ character array contains any lexical namelist tokens, such as `&` or
40
+ `/`, then any non-delimited values may be misinterpreted as part of the
41
+ namelist object structure.
47
42
48
- The standard acknowledges the limitations of non-delimited character array
49
- parsing, and specifically directs the interpreter to ignore the value of
50
- DELIM when reading a namelist (12.5.6.8).
43
+ The standard acknowledges the limitations of non-delimited character
44
+ array parsing, and specifically directs the interpreter to ignore the
45
+ value of DELIM when reading a namelist (12.5.6.8).
51
46
52
47
The scalar-default-char-expr shall evaluate to APOSTROPHE, QUOTE, or
53
48
NONE. The DELIM= specifier is permitted only for a connection for
54
- formatted input/output. It specifies the delimiter mode (12.6.2.8) for
55
- list-directed (13.10.4) and namelist (13.11.4.2) output for the
49
+ formatted input/output. It specifies the delimiter mode (12.6.2.8)
50
+ for list-directed (13.10.4) and namelist (13.11.4.2) output for the
56
51
connection. This mode has no effect on input.
57
52
58
- However, despite the acknowledgement of the issues above, the default
59
- behavior of a WRITE command is to produce non-delimited character arrays.
60
- From 13.11.4.2p1,
53
+ However, despite the acknowledgment of the issues above, the default
54
+ behavior of a WRITE command is to produce non-delimited character
55
+ arrays. From 13.11.4.2p1,
61
56
62
- Values in namelist output records are edited as for list-directed output
63
- (13.10.4).
57
+ Values in namelist output records are edited as for list-directed
58
+ output (13.10.4).
64
59
65
- This is done despite the fact that list-directed output follows different
66
- I/O rules for character arrays. From 13.10.3.1p7 (my emphasis),
60
+ This is done despite the fact that list-directed output follows
61
+ different I/O rules for character arrays. From 13.10.3.1p7 (my
62
+ emphasis),
67
63
68
64
When the next effective item is of type character, the input form
69
- consists of a **possibly** delimited sequence of zero or more rep-chars
70
- whose kind type parameter is implied by the kind of the effective item.
65
+ consists of a **possibly** delimited sequence of zero or more
66
+ rep-chars whose kind type parameter is implied by the kind of the
67
+ effective item.
71
68
72
- The namelist specification 13.11.3.3p7 deliberately omits "possibly" from
73
- its description.
69
+ The namelist specification 13.11.3.3p7 deliberately omits "possibly"
70
+ from its description.
74
71
75
- In other words, list-directed output permits non-delimited arrays, whereas
76
- namelists do not. In addition, the default value of DELIM is to revert
77
- back to its value in the OPEN call. From 12.5.6.8p1,
72
+ In other words, list-directed output permits non-delimited arrays,
73
+ whereas namelists do not. In addition, the default value of DELIM is to
74
+ revert back to its value in the OPEN call. From 12.5.6.8p1,
78
75
79
76
If this specifier is omitted in an OPEN statement that initiates a
80
77
connection, the default value is NONE.
@@ -83,26 +80,120 @@ The default behavior of a WRITE call using namelist data is therefore to
83
80
produce an output which is non-conformant with the namelist standard.
84
81
85
82
86
- Proposal
87
- ========
83
+ 3. Example
84
+
85
+ Consider the program listed below, which will produce a namelist
86
+ containing a single group `sample_nml`, containing a single character
87
+ array, `input`.
88
+
89
+ program writenml
90
+ implicit none
91
+ character(len=20) :: input
92
+ namelist /sample_nml/ input
93
+
94
+ input = trim("some/path/to/file")
95
+ open(5, file="out.nml")
96
+ write(5, nml=sample_nml)
97
+ end program writenml
98
+
99
+ According to the interpretation above, the absence of a DELIM argument
100
+ means that `input` is formatted with no delimiter. A
101
+ standard-conforming output would be
102
+
103
+ &SAMPLE_NML
104
+ INPUT = some/path/to/file
105
+ /
106
+
107
+ For this example, we have used the output produced by the Intel Fortran
108
+ Compiler 19.0.5.281.
109
+
110
+ Now consider the following program, which reads this namelist.
111
+
112
+ program readnml
113
+ implicit none
114
+ character(len=20) :: input
115
+ namelist /sample_nml/ input
116
+
117
+ open(5, file='out.nml')
118
+ read(5, nml=sample_nml)
119
+
120
+ open(6, file='new.nml')
121
+ write(6, nml=sample_nml)
122
+ end program readnml
123
+
124
+ The namelist `new.nml` produced by this program is the following.
125
+
126
+ &SAMPLE_NML
127
+ INPUT = some
128
+ /
129
+
130
+ The namelist group `sample_nml` is terminated after the first `/` token,
131
+ and any characters following the token are ignored.
132
+
133
+ Although the interpretation is correct, it also means that a write
134
+ statement of the following form
135
+
136
+ write(unit, nml=filename)
137
+
138
+ where the DELIM argument is unset will produce namelists which are
139
+ non-conforming. The fact that this is not only possible, but is the
140
+ default behavior, is counterintuitive and is likely to introduce errors
141
+ into namelist I/O operations.
142
+
143
+ As an aside, we note that GNU Fortran explicitly breaks from the
144
+ standard and does produce a quote-delimited namelist, such as the one
145
+ shown below.
146
+
147
+ &SAMPLE_NML
148
+ INPUT="some/path/to/file ",
149
+ /
150
+
151
+ This namelist above was produced by GNU Fortran 9.2.1.
152
+
153
+
154
+ 4. Proposal
88
155
89
156
We propose one of the following additions to the *io-control-spec-list*,
90
157
detailed in 12.6.2.1.
91
158
92
- A. If *namelist-group-name* appears, then a DELIM= specifier with the value
93
- of either APOSTROPHE or QUOTE shall also appear.
159
+ A. If *namelist-group-name* appears, then a DELIM= specifier with the
160
+ value of either APOSTROPHE or QUOTE shall also appear.
94
161
95
- Option A would take the current recommended advice to always use DELIM when
96
- writing namelist output and turn it into an explicit rule. However, it
97
- would cause currently compliant code to be non-compliant, and may require
98
- modifications if used by future interpreters.
162
+ Option A would take the current recommended advice to always use DELIM
163
+ when writing namelist output and turn it into an explicit rule. The
164
+ following statement would constitute an error
99
165
100
- B. If *namelist-group-name* appears and a DELIM= specifier has the value of
101
- NONE, then this value is ignored and the data transfer uses a value of
102
- APOSTROPHE.
166
+ write(unit, nml=filename)
103
167
104
- Option B would change the behavior of existing standard-compliant
105
- interpreters, in that non-delimited character arrays would be replaced with
106
- apostrophe-delimited arrays. But existing source code would otherwise
107
- remain compliant and continue to compile on both older and newer
168
+ and would require the user to include a DELIM argument, e.g.
169
+
170
+ write(unit, nml=filename, delim="quote")
171
+
172
+ This would also mean that currently compliant code missing a DELIM would
173
+ be non-compliant, and may require modifications if used by future
108
174
interpreters.
175
+
176
+ B. If *namelist-group-name* appears and a DELIM= specifier has the value
177
+ of NONE, then this value is ignored and the data transfer uses a
178
+ value of APOSTROPHE.
179
+
180
+ Option B would change the behavior of existing standard-compliant
181
+ interpreters, in that non-delimited character arrays would be replaced
182
+ with apostrophe-delimited arrays. But existing source code would
183
+ otherwise remain compliant and continue to compile on both older and
184
+ newer interpreters.
185
+
186
+
187
+ 5. Reference
188
+
189
+ Discussion of this issue on the Intel Fortran forums:
190
+
191
+ https://software.intel.com/en-us/forums/intel-fortran-compiler/topic/831685
192
+
193
+ Discussion of GNU Fortran's decision to use quote delimiters:
194
+
195
+ https://gcc.gnu.org/ml/gcc-patches/2014-03/msg00030.html
196
+
197
+ Initial submission and discussion to the J3 Fortran Github repository:
198
+
199
+ https://github.com/j3-fortran/fortran_proposals/pull/94
0 commit comments