Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
Welcome to the Intel Community. If you get an answer you like, please mark it as an Accepted Solution to help others. Thank you!
26757 Discussions

Write statement operates differently with compiler XE2019

Annegarn__Paul
Beginner
114 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
114 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

IanH
Black Belt
114 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.

jimdempseyatthecove
Black Belt
114 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

mecej4
Black Belt
114 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!

Annegarn__Paul
Beginner
114 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

mecej4
Black Belt
114 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.

FortranFan
Honored Contributor II
114 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.

 

Annegarn__Paul
Beginner
114 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

Reply