I am not sure this is the right place to report this kind of problem, I apologize if this post is misplaced.
It seems to me having non-delimited strings by default when writing a namelist to a file is not a sensible choice. Non-delimited strings are not standard, and this format doesn't guarantee the string value will be correctly recovered when read. I suggest strings be delimited by default when writing a namelist.
See the example hereafter (tested with ifort 17, if this problem is fixed now then I apologize for the inconvenience). I guess other characters beside `/` would also lead to issues when reading the string.
program strnml implicit none character(len=6) :: s namelist /test/ s s = 'op/out' open(5, file="test.nml", status='new') ! opening with delim='quote' fixes the issue, this should be ! the default behavior write(5,test) close(5) open(5, file="test.nml") read(5,test) close(5) ! prints "op" instead of the expected "op/out" print *, s end program strnml
Hi Steve, I'm trying to walk through the 2018 Draft and was hoping you could comment on my interpretation below.
188.8.131.52 p7 seems (to me at least) to say that a namelist character array must be delimited by single or double quotes:
When the next effective item is of type character, the input form consists of a sequence of zero or more rep-chars
whose kind type parameter is implied by the kind of the corresponding list item, delimited by apostrophes or
Note 13.36 emphasizes the potential for ambiguity if the quotes were to be absent.
If we move on to output, then 184.108.40.206 says output follows list-directed output, of which three options are provided: None, single quote, double quote.
Note 13.40 then echos your point that DELIM=NONE output may not be valid input:
Namelist output records produced with a DELIM= specifier with a value of NONE and which contain a
character sequence might not be acceptable as namelist input records.
- Does this mean that list-directed output and namelist input are potentially incompatible? Does it make sense for namelists to support list-directed output, and non-delimited strings in particular?
- Is the Intel compiler in violation of the Standard for accepting non-delimited strings?
- Is DELIM=NONE required to be the default behavior for a WRITE() call?
- Finally, is it worth raising these issues with the Standard committee?
I know that interpreting the Standard can be a minefield, so no doubt there are details that I've missed.
1. Yes, they are potentially incompatible, which is why the note is there. If you are using NAMELIST I/O, you should specify a DELIM= value for the unit other than NONE.
2. No. The standard says which input forms are acceptable to the standard. Non-delimited strings are not standard-conforming and thus the implementation may choose to accept or reject them as it wishes. Intel Fortran accepts many things in list-directed and NAMELIST input not specified in the standard, all perfectly ok as far as the standard is concerned. (For years I lobbied to get the free conversion between LOGICAL and numeric disabled in list-directed and NAMELIST input, as it was a continuing source of complaints from users. That finally happened around version 14, I think, with a switch to reenable it.)
3. It is the default when a unit is opened, if you don't say otherwise. This includes preconnected units.
4. No - that ship sailed 30 years ago.
So, if I understand right:
- A namelist with non-delimited strings does not conform to the namelist standard, but...
- an implementation is not required to follow the namelist standard (or any input format, for that matter), and may accept as needed, regardless of how that format may be specified?
Is that correct?
On a related note, does that mean that (for example) GNU is violating the standard by writing character arrays with quote delimiters when DELIM is unset? That would be my interpretation from your reply to #3, as well as your first comment.
The standard describes the behavior of a program whose source and inputs conform to what the standard says. It does not specify behavior if either of those is violated. This opens the door to extensions but sometimes also hard-to-understand differences in run-time behavior.
If gfortran is writing character data in list-directed or NAMELIST with delimiters without the user having used DELIM='QUOTE' or 'APOSTROPHE', that would be nonconforming in my opinion. The standard says, :"If the connection is initiated other than by an OPEN statement (that is, if the file is an internal file or preconnected file) the values established are those that would be implied by an initial OPEN statement without the corresponding keywords."
and then for OPEN (DELIM=) it says, "If this specifier is omitted in an OPEN statement that initiates a connection, the default value is NONE."
I don't have a recent version of gfortran around - can you demonstrate that?
I see, so if the input conforms to a namelist as described in the standard, then one can presume that it will interpreted as a namelist. If not, then it is UB and the behavior is at the discretion of the compiler.
As for gfortran, if I run Adrien's example code above then gcc 9.2.0 gives me the following namelist:
&TEST S="op/out", /
and defaults to QUOTE delimiters. I wasn't able to find a way to produce a namelist without delimiters.
It does feel a bit paradoxical that an output "namelist" is not necessarily a valid namelist, as you alluded to in your first post, but I feel like I understand the interpretation now. Thanks very much for walking me through it.
I sent this off to one of the gfortran developers and he pointed me to https://gcc.gnu.org/ml/gcc-patches/2014-03/msg00056.html where this had been discussed in 2014. In the end they chose to not change the default, which is a position I can support, as it would break programs dependent on the previous behavior. gfortran does now fully support DELIM= (it didn't for a long time), and it's a "changeable mode" so you can even set it for the default output unit. The standard-specified behavior is not useful, in my opinion, and I'd expect most users will have already opened the unit with a DELIM= value of their choosing.
Thanks for following up with the gfortran folks, it's good to know that they understand the situation, but opted to continue using delimiters. It seems the most user-friendly choice, even if it doesn't conform to the standard.
I'll also pass on the advice to use DELIM= with namelist I/O writes. For better or worse, it is common to store path names inside of namelists, which can include quite a few backslashes!