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

writing to standard output in a character returning function has weird effect

franck_reinquin
1,006 Views

Hello,

We have encountered something strange with the following code :

module char_function_mod
contains
  function char_function() result(returned_string)
    !
    !.. Formal Arguments ..
    character(len=19) :: returned_string

    returned_string='2023-11-09 09:02:00'
    !write(6,"('INTERNAL PRINT=',a)") returned_string
    return
  end function char_function

end module char_function_mod

! -----------------------------
program test_char_function
  use char_function_mod
  implicit none
  real :: a_real

  a_real=26414.376395
  write (6,"('a real=',f15.9)") a_real
  write(*,"('--------')")
  write (6,"('the string :',a)") trim(char_function())
  write(*,"('--------')")
  write (6,"('a real=',f15.9,' and the string :',a)") a_real, trim(char_function())

end program test_char_function

It was tested both with :

ifort (IFORT) 2021.10.0 20230609

ifx (IFX) 2023.2.0 20230721

and gives the correct result below when the 'INTERNAL PRINT' output is commented out :

a real=26414.376395000
--------
the string :2023-11-09 09:02:00
--------
a real=26414.376395000 and the string :2023-11-09 09:02:00

However, when the write is active, here is what we get :

a real=26414.376395000
--------
INTERNAL PRINT=2023-11-09 09:02:00
the string :2023-11-09 09:02:00
--------
INTERNAL PRINT=2023-11-09 09:02:00
INTERNAL PRINT=2023-11-09 09:02:00INTERNAL PRINT=2023-11-09 09:02:00

The last write is corrupted.

Should I file a bug report through the support center or am I completely wrong in the diagnosis ?

Franck

0 Kudos
1 Solution
jimdempseyatthecove
Honored Contributor III
980 Views

Your code has a nested write (to the same channel). I suspect that this is non-conformant to the Fortran standard. Steve would be the expert on this.

 

Jim Dempsey

View solution in original post

9 Replies
jimdempseyatthecove
Honored Contributor III
981 Views

Your code has a nested write (to the same channel). I suspect that this is non-conformant to the Fortran standard. Steve would be the expert on this.

 

Jim Dempsey

Arjen_Markus
Honored Contributor I
970 Views

IIUIC, writing in a nested way to different channels is allowed nowadays, but indeed using the same channel wrecks havoc.

franck_reinquin
969 Views

Yes, that sounds logical. Thanks !

Franck

0 Kudos
jimdempseyatthecove
Honored Contributor III
961 Views

You might consider something like this:

module char_function_mod
contains
  function char_function() result(returned_string)
    !
    !.. Formal Arguments ..
    character(len=:), allocatable :: returned_string
    returned_string='2023-11-09 09:02:00'
    ! comment or uncomment the following line
    returned_string = 'INTERNAL PRINT=' // returned_string
    return
  end function char_function

end module char_function_mod

! -----------------------------
program test_char_function
  use char_function_mod
  implicit none
  real :: a_real

  a_real=26414.376395
  write (6,"('a real=',f15.9)") a_real
  write(*,"('--------')")
  write (6,"('the string :',a)") trim(char_function())
  write(*,"('--------')")
  write (6,"('a real=',f15.9,' and the string :',a)") a_real, trim(char_function())

end program test_char_function

Jim Dempsey

 

0 Kudos
jimdempseyatthecove
Honored Contributor III
951 Views

Or consider:

returned_string = char(13) // char(10) // 'INTERNAL PRINT='  // returned_string // char(13) // char(10)

 

Jim Dempsey

0 Kudos
franck_reinquin
942 Views

Actually this 'INTERNAL PRINT' text was temporary, just for debugging some other problem. As you may guess, the real code is much different, I extracted only the minimum code that showed the behavior we couldn't explain.

I would use unit 0 (standard error) for this purpose when the prints are to stay forever, but I am not the one who added that one.

Thanks a lot for your time, Jim.

Franck

0 Kudos
David_Billinghurst
New Contributor III
850 Views

In The new features of Fortran 2008 (ISO/IEC JTC1/SC22/WG5 N1828) by John Reid we have

7.4 Recursive input/output
It is useful to be able to perform I/O in a subprogram invoked during the processing of an I/O statement (e.g., for tracing and diagnostic purposes). This is now permitted for an external unit that is distinct from that of an I/O statement that is in execution (that is, any in the current call chain).

That I understand.

The Fortran 2018 standard, in Section 12.12 Restrictions on input/output statements, paragraph 2 says

An input/output statement that is executed while another input/output statement is being executed is a recursive input/output statement. A recursive input/output statement shall not identify an external unit that is identified by another input/output statement being executed except that a child data transfer statement may identify its parent data transfer statement external unit.

The draft Fortran 2023 standard is identical.  I struggle to parse that, but it seems to suggest the opposite.  Can anyone explain it to me?

0 Kudos
JohnNichols
Valued Contributor III
822 Views

I will try and explain it in the vernacular of the Northern Territory, circa 1975, 

Mate I am gunna take a ................, do not touch my beer, the guy is drinking a white can, so I would sooner write Fortran at dawn in my pj's. 

Mate's daughter walks in the pub, which means at the time she is at least 15, looks at the man who has been like an uncle to her for as long as she can remember, held her head the first time she threw up a beer and never told a soul,  asking "is that the old Bloke's"

Silent head nod, the young lady swiftly dispatches the beer, puts it down and takes a seat,. her uncle orders her a lemonade.

Mate returns from the ..........................................., picks up beer, it is empty, uncle mate says, never touched the stuff, the old man knows it was his daughter, but he is afraid of her mother, so he just buys the next shout. 

In that vernacular, the story is true according to rule set 2 and not according to rules set 1, which often happens with daughters, of course my third daughter would have drunk her "uncle's" beer as well, but she is not fussy, she likes white and green cans, she would turn the lemonade into a shandy.

I hope that explains the paradox of daughters and Fortran standards.  I prefer my version

 

 

 

0 Kudos
Barbara_P_Intel
Employee
791 Views

@David_Billinghurst, I checked with my go-to guy who can read and understand the Fortran standard better than me.

He wrote, "What the standard says is exactly the same thing as Modern Fortran Explained with a caveat. The external unit that is used by the parent I/O statement may be used by a child I/O statement. That is to say, the child I/O statement may read or write to the same file that its parent I/O statement is reading or writing to."

 

0 Kudos
Reply