- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
program testzero
implicit none
character(len=:),allocatable :: line(:), input
integer :: ints(3), i, j, k, l, m, n, iostat
namelist /nml/ i,j,k,l,m,n
character(len=256) :: iomsg
! zero data-repeat-specification allows for a zero
data ints/ 1*-10,0*-20,2*-30 /
write(*,*)ints
! list-directed input does something different with each compiler
! but gfortran stops saying not allowed
input='1*10,0*20,2*30'
read(input,*,iostat=iostat,iomsg=iomsg)i,j,k
if(iostat.ne.0)write(*,*)trim(iomsg)
write(*,*)i,j,k
read(input,*,iostat=iostat,iomsg=iomsg)ints
if(iostat.ne.0)write(*,*)trim(iomsg)
write(*,*)ints
! ifort does something weird, which gets weirder
i=-10;j=-20;k=-30;l=-40;m=-50;n=-60
read(input,*,iostat=iostat,iomsg=iomsg)i,j,k,l,m,n
if(iostat.ne.0)write(*,*)'TOO MANY:'//trim(iomsg)//':'//input
write(*,*)i,j,k,l,m,n
! repeat specification is supposed to be "positive"
!write(*,'(2("A",i0:,1x),0("B",i0:,1x),3("C",i0:,1x))') 1,2,3,4,5
! namelist input
i=-1;j=-2;k=-3;l=-4;m=-5;n=-6
line=[character(len=80) :: '&nml', 'i=11,j=22,k=33,l=44,m=55,n=66', '/']
read(line,nml=nml,iostat=iostat,iomsg=iomsg)
if(iostat.ne.0)write(*,'(" > ",a)') 'NAMELIST:'//trim(iomsg)//':',line
write(*,*)i,j,k,l,m,n
write(*,nml=nml)
end program testzero
I was testing repeat specifiers, and as part of that was looking at where zero was allowed as a repeat count, as it is definitely allowed in a DATA statement. If not allowed I was expecting an error, or expecting it to act as a zero. I did not get errors with ifort, and got very unexpected results with the following test code:
ifort testzero.f90
(base) urbanjs@venus:~/github/fun/weird_io/app$ ./a.out
-10 -30 -30
10 20 20
10 20 20
10 20 20 20 20 20
11 22 33 44 55 66
&NML
I = 11,
J = 22,
K = 33,
L = 44,
M = 55,
N = 66
/
There were other issues when I added 0 as a repeat specifier in NAMELIST input not shown.
I found one line in the f2018 standard for one case saying the repeat count had to be "positive" which might be implying non-zero; but only the DATA statement specifically said zero was allowed.
Either way, I would expect these to work as if zero meant no repeat of the following value, or to generate an error. Neither occurs.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This behaves as if all values are ten on a read, it is indeed interesting, but data statements are so not cool.
input='0*10,0*20,3*30'
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Repeat specifiers appear in Fortran in several circumstances. One would hope that they behave consistently. The DATA statement clearly describes the behavior and specifically states a repeat count of zero is allowed. In other locations in the standard for NAMELIST groups, list-directed I/O, FORMAT declarations, and so on I did not find any descriptions as clear. Some did not appear to state what was allowed, and others said the value should be positive, but were not as clear about whether a positive zero was considered positive or not.
The actual case of interest is actually FORMATs that are generated on the fly where the repeat required is calculated and written into a string to be used as a FORMAT, but the general question was is zero allowed in that case, and more generally what is the behavior in all the cases where repeats are allowed?
Some compilers gave error messages, some gave segfaults, etc ... . The ifort compiler did not generate an error, but did also not act correctly if zero is allowed. So I am not sure if an error should be produced, or if zero should be allowed; but the above test case shows no errors in several cases but also does not behave as if zero is allowed, but appears to produce very unexpected results; including returning more non-zero values than are present in the input, and unexpected values. So either way I think those are bugs; but not sure what to report until it is determined what the standard behavior should be.
Although DATA statements are superior in many ways for easily declaring arrays in row-column order, partially declaring values, and so on I have not added on in years; although I use a lot of code that has DATA statements in them. It is referenced here because it is one of the statements that allows repeat specifiers and also has the clearest specification in the standard, and clearly states zero repeats are allowed, and is the one case where ifort behaved as expected.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@ur,
The standard document for Fortran suggests only the DATA statement allows a zero datat-stmt-repeat value.
The standard requires the list-directed IO as well as NAMELIST to have a nonzero, nonsigned int-literal-constant as the repeat value in the "r*c" form allowed for the statement. Thus your code does not conform. There are no numbered constraints indicated in the standard thus it is the programmer's responsibility to conform to the standard, the compiler is not required to detect and report nonconformance and the program behavior can be anything.
As to the DATA statement with a zero repeat, two compilers I tried appear to process it alright:
integer :: x
data x / 0 * 1, 42 / !<-- first listing should get ignored
print *, "x = ", x, "; expected is 42"
end
C:\temp>ifort /standard-semantics p.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.7.0 Build 20220726_000000
Copyright (C) 1985-2022 Intel Corporation. All rights reserved.
Microsoft (R) Incremental Linker Version 14.33.31630.0
Copyright (C) Microsoft Corporation. All rights reserved.
-out:p.exe
-subsystem:console
p.obj
C:\temp>p.exe
x = 42 ; expected is 42
C:\temp>gfortran p.f90 -o gcc-p.exe
C:\temp>gcc-p.exe
x = 42 ; expected is 42
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@FortranFan, there is a subtle difference between your code and @ur code, that code generates a problem on the read from data with a read statement. The read statement stops at the first 0*1 - I agree with @ur it is a bit annoying, I still think data statements are a lousy way to incorporate constants into a program, they can get buried deep in the code and you do not realize their significance. Very easy to introduce an incorrectly typed number, the recent prestressed program I played with had such a problem.
In terms of 0 repeater on the format, it should throw an error.
Just my humble Sunday morning opinion.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
When you use an internal I/O character variable that may contain a "0*nnn," (with or without ","), prior to use, remove the 0*nnn (with or without ",").
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This is probably worth a feature request to print an error message. I'll talk to the runtime library gurus today with this example.
but a comment in the code has me confused. your comment states
10 ! list-directed input does something different with each compiler
11 ! but gfortran stops saying not allowed
I'm not seeing that behavior of stopping with gfortran 12.0.1 on linux:
$ gfortran -o testzero testzero.f90
rwgreen@orcsle153:~/quad$ ./testzero
-10 -30 -30
Zero repeat count in item 2 of list input
10 -706010880 0
Zero repeat count in item 2 of list input
10 -30 -30
TOO MANY:Zero repeat count in item 2 of list input:1*10,0*20,2*30
10 -20 -30 -40 -50 -60
11 22 33 44 55 66
&NML
I=11 ,
J=22 ,
K=33 ,
L=44 ,
M=55 ,
N=66 ,
/
gfortran --version
GNU Fortran (GCC) 12.0.1 20220413 (Red Hat 12.0.1-0)
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here's what NAG Fortran 7.1 outputs:
-10 -30 -30
Zero repeat factor in list-directed input
10 0 0
Zero repeat factor in list-directed input
10 -30 -30
TOO MANY:Zero repeat factor in list-directed input:1*10,0*20,2*30
10 -20 -30 -40 -50 -60
11 22 33 44 55 66
&NML I = 11, J = 22, K = 33, L = 44, M = 55, N = 66/
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I was reading my steel design manual last night. Light reading after a day fixing the ethernet cables placed in house upon construction. I finally got round to connecting them up. Two longest runs had open circuits, both in very hard to reach attic corners. One I could pull, the other I kept cutting and trying till it was not open and then attached another good cable. Now all the white cables snaking through the house are gone.
So the steel manual suggests if you have two independent variables if they are 1:1000 each the odds of both simultaneously is 1 in a million, so @ur has found an odd combinations with data and read and format.
I am sure most old timers, anyone who thinks Die Hard is the best Christmas movie and who graduated Middle School between 1965 and 1972, would not try this combination.
The reason for allowing zeros in data is clearly to allow the list to be amended quickly, it should not be allowed, and the lack of a warning on zero format should be an error, IMHO.
Now I will be told why I am wrong. Plus why read from a data statement you can use = to do the same thing can you not and it is a lot clearer, so reading from a data statement is verbotten.
My two penny's worth.
Thought for the day, if you take a nation, let us call it Old Blighty, and it now has a GDP that is 70% of what it was six years ago, is the political decision that made that change a good one. LOL
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It appears our RTL is taking the 0* as an infinite repeat count. I modified the test thusly to get more clarity:
program testzero
implicit none
character(len=:),allocatable :: line(:), input
integer :: ints(3), i, j, k, l, m, n, iostat
namelist /nml/ i,j,k,l,m,n
character(len=256) :: iomsg
! zero data-repeat-specification allows for a zero
data ints/ 1*-10,0*-20,2*-30 /
write(*,*) "test 1: data statement data ints/ 1*-10,0*-20,2*-30 /"
write(*,*) "ints array contains: ", ints
write(*,*) ""
! list-directed input
input='1*10,0*20,2*30'
write(*,*) "test 2: internal read to uninit i,j,k of input: ", input
write(*,*) "read(input,*,iostat=iostat,iomsg=iomsg)i,j,k"
read(input,*,iostat=iostat,iomsg=iomsg)i,j,k
write(*,*) "iostat is ", iostat
if (iostat /= 0) write(*,*) "iomsg is ", trim(iomsg)
write(*,*) "i, j, k after read: ", i,j,k
write(*,*) ""
write(*,*) "test 3: internal read to existing 3 elements of ints of input: ", input
write(*,*) "read(input,*,iostat=iostat,iomsg=iomsg) ints"
read(input,*,iostat=iostat,iomsg=iomsg) ints
write(*,*) "iostat is ", iostat
if (iostat /= 0) write(*,*) "iomsg is ", trim(iomsg)
write(*,*) "ints(3) after read: ", ints
write(*,*) ""
write(*,*) "test 4: initialize i=-10;j=-20;k=-30;l=-40;m=-50;n=-60"
write(*,*) "then read just 3 elements of input: ", input
write(*,*) "read(input,*,iostat=iostat,iomsg=iomsg)i,j,k,l,m,n"
i=-10;j=-20;k=-30;l=-40;m=-50;n=-60
read(input,*,iostat=iostat,iomsg=iomsg)i,j,k,l,m,n
write(*,*) "iostat is ", iostat
if (iostat /= 0) write(*,*) "iomsg is ", trim(iomsg)
write(*,*) "i,j,k,l,m,n after read: ",i,j,k,l,m,n
write(*,*) ""
end program testzero
note that I removed the namelist since that seems to work. I could/should remove the data statement test as well.
Our output with IFX and IFORT (same RTL) is:
./testzero
test 1: data statement data ints/ 1*-10,0*-20,2*-30 /
ints array contains: -10 -30 -30
test 2: internal read to uninit i,j,k of input: 1*10,0*20,2*30
read(input,*,iostat=iostat,iomsg=iomsg)i,j,k
iostat is 0
i, j, k after read: 10 20 20
test 3: internal read to existing 3 elements of ints of input: 1*10,0*20,2*30
read(input,*,iostat=iostat,iomsg=iomsg) ints
iostat is 0
ints(3) after read: 10 20 20
test 4: initialize i=-10;j=-20;k=-30;l=-40;m=-50;n=-60
then read just 3 elements of input: 1*10,0*20,2*30
read(input,*,iostat=iostat,iomsg=iomsg)i,j,k,l,m,n
iostat is 0
i,j,k,l,m,n after read: 10 20 20 20
20 20
I am in talks with our RTL team. Since the code does not conform it may be a feature request as opposed to a bug.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
it's a bug. I'll write it up and we'll get a warning message similar to NAG's and Gfortran's messages
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks everyone for going farther than expected. I was only hoping for clarification on whether a zero repeat specifier was allowed/supported anywhere other than in a DATA statement, and got that and far more. So everyone agrees there is not
support for zero repeaters in anything else (NAMELIST groups, list-directed I/O, VFE extension, ...)? Thanks for the fix on the
infinite read, and for the enhancements that will make programming with ifort more robust. If it is possible to make the error
you get with VFE use of a zero repeater (it errors out on use, but note not on presence ) that would be less confusing as well.
Thanks to everyone for the responses; several are solutions to different parts of this. Note the NAMELIST placeholder does cause errors with a zero repeater as well, the example just does not use one in the posted example; which was in process when the infinite read showed up which really got confusing.
program demo_vfe
implicit none
character(len=*),parameter :: template="(1x, <left>('<',i0:,1x), <middle>('@',i0:,1x), <right>('>',i0:,1x))"
integer,allocatable :: vector(:)
integer :: left, middle, right, i
integer :: iostat
character(len=256) :: iomsg
! test extension
left=3
middle=4
right=5
vector=[1,2,3,4,5,6,7,8,9,10,11,12]
write(*, template,iostat=iostat,iomsg=iomsg) vector
if(iostat.ne.0)write(*,*)'*iomsg*:'//trim(iomsg)
left=0
middle=0
right=12
vector=[1,2,3,4,5,6,7,8,9,10,11,12]
write(*, template,iostat=iostat,iomsg=iomsg) vector
if(iostat.ne.0)write(*,*)'*iomsg*:'//trim(iomsg)
left=12
middle=0
right=0
vector=[1,2,3,4,5,6,7,8,9,10,11,12]
write(*, template,iostat=iostat,iomsg=iomsg) vector
if(iostat.ne.0)write(*,*)'*iomsg*:'//trim(iomsg)
end program demo_vfe
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
bug ID CMPLRLIBS-34183
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Note that NAG and gfortran don't emit messages - those in the output come from the program.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
the zero repeat error was fixed and is in the 2023.0 compilers.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page