Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28385 Discussions

Write statement operates differently with compiler XE2019

Annegarn__Paul
Beginner
422 Views

XE2019 compared to XE2016:

Consider Fortran Code:

Character*4  s

s = '1234'

Write( s, '(A4)') s

The string 's' is empty with XE2019 and contains '1234' with XE2016.

I know this code looks silly. It is what I found in my project. And maybe other constructions are involved as well.

Can I prevent this changed behavior with a compiler setting? Or will it be fixed?

0 Kudos
8 Replies
FortranFan
Honored Contributor II
422 Views

It looks like a bug in Intel Fortran compiler.  Your best option may be to submit a request at Intel support center: https://supporttickets.intel.com/servicecenter?lang=en-US

0 Kudos
IanH
Honored Contributor II
422 Views

Note the code is non-conforming. 

The standard requires that "If an internal file has been specified, an input/output list item shall not be in the file or associated with the file" (F2018 12.6.4.5.1p6).  In the example code, the sole input list item `s` is the internal file.

0 Kudos
jimdempseyatthecove
Honored Contributor III
422 Views

Try:

program write_s
    character*4 s
    s = '1234'
    write(s,'(A4)') s // 'hack'
    print *, s
end program write_s

Your actual code may want to concatenate '    '

Jim Dempsey

0 Kudos
mecej4
Honored Contributor III
422 Views

IanH (Blackbelt) wrote:

Note the code is non-conforming. 

The standard requires that "If an internal file has been specified, an input/output list item shall not be in the file or associated with the file" (F2018 12.6.4.5.1p6).  In the example code, the sole input list item `s` is the internal file.

Thanks, Ian, for the quote.

When I saw the program a few hours ago, I sensed that there was something wrong with having the same variable as the internal file and in the I/O list. Many compilers implement the WRITE statement with subroutine calls to the RTL; in such a call, the file variable would be intent(out), and the same variable in the I/O list would be intent(in) -- and, this would be an instance of aliased arguments, if the RTL routines were written in Fortran. I could not find the relevant part of the standard by searching with "internal file".

The same prohibition can be found in 9.5.3.3 Establishing a format of F2003 and 9.6.4.4 Establishing a format of F2008.

I wonder if there is any compiler that, with runtime checks enabled, is able to catch this error!

0 Kudos
Annegarn__Paul
Beginner
422 Views

Thanks all for the reply. 2 remarks:

- Previously the compiler managed to handle it as I described. Why did it change? Did Intel changed it to comply?

- It's hard to find this code in more then 100000 lines of Fortran. That's why I can't use Jim's trick while it works. I don't know at the first place why this code was used because at the best nothing will happen! So I dropped it at the spot where I found it. My concern: Is this used more?

Thanks again for the help.

Paul

0 Kudos
mecej4
Honored Contributor III
422 Views

I found one way of locating a source line in a Fortran program in which an internal file is also a member of the I/O list. Depending on how badly you wish to fix this problem, it may be worth trying.

The Lahey Fortran 90 compiler produces a cross-reference listing if asked. In the listing file generated, look for lines containing CHARACTER followed by the pattern <decimal-number>o . Note the second line in the LF90 cross-reference listing for your test program (with a couple of changes that I made):

I (INTEGER)           scalar                      3s     6=     6u     6u     6u
S (CHARACTER)         scalar                      2s     5o     5o     5o     5o     6r
SILLY                 Procedure                   1s
T (CHARACTER)         scalar                      2s

Running the listing file through the Cygwin utility grep with the command

grep "CHARACTER.*scalar.*[0-9]o " silly.lst

catches this line (and other lines where a character variable is used as an output list item. You could do a similar search for internal READs.

0 Kudos
FortranFan
Honored Contributor II
422 Views

Annegarn, Paul wrote:

Thanks all for the reply. 2 remarks:

- Previously the compiler managed to handle it as I described. Why did it change? Did Intel changed it to comply?

- It's hard to find this code in more then 100000 lines of Fortran. That's why I can't use Jim's trick while it works. I don't know at the first place why this code was used because at the best nothing will happen! So I dropped it at the spot where I found it. My concern: Is this used more?

Thanks again for the help.

Paul

@Paul,

I still suggest you submit a support request with Intel OSC: https://supporttickets.intel.com/servicecenter?lang=en-US  You can inquire of Intel Fortran team's plans re: the situation you show in the original post with an internal file.  Previous versions of Intel Fortran compiler supported your use case for which there is not a constraint and a prohibition in the standard.  In response to your request, Intel Fortran team might be able to flag the offending internal file IO as a compile-time warning (say with /warn:xx) or raise a run-time exception, say when /check:xx is in effect as opposed to the current situation where no warnings or errors appear to be used and the run-time is undefined behavior, none of which meets the "spirit" of a commercial product.

 

0 Kudos
Annegarn__Paul
Beginner
422 Views

Thanks for the idea. I'm using Visual Studio with Intel parallel composer. However I might do something simular with a regular expression.

Paul

0 Kudos
Reply