Code Comments
Programming Forum and web based access to our favorite programming groups.Harald Anlauf wrote: ... > what is the status of recursive I/O on internal files in Fortran 95? James van Buskirk already answered your question. > I have a book on my desk that is rather unclear on that point and can > be read as allowing it in that particular case. > > I checked the F2k3 draft, where in section 9.11 it appears that it is > allowed (now?), although I have a hard time understanding the following > excerpt: > > "A recursive input/output statement shall not modify the value of any > internal unit except that a recursive WRITE statement may modify the > internal unit identified by that recursive WRITE statement." > > I'm not a native speaker, so can somebody please explain it in some > detail? It should be noted that the word "recursive" here is a bit of a misnomer. The I/O is not really being done recursively, but on some iomplementations you are doint something that may require the I/O library to be reentrant. > program test_rec_io > implicit none > character (len=4) :: s > write (s, '(a)') foo (1234) > write (*,*) s > > contains > > pure recursive function foo (i) result (s) > integer, intent(in) :: i > character (len=4) :: s > ! Internal I/O, allowed recursive in f2k3 > write (s, '(i4.4)') i > end function foo > > end program test_rec_io In F2003, the above does not need the "recursive" keyword since foo does not call itself, either directly or indirectly. However, the I/O library procedures that do internal write *may* (depending on implementation) be calling themselves indirectly. It's possible, though not a usual implementation, for the call to foo to actually be made from within the I/O library itself. In such an unusual implementation, there really would be recursion. In most implementations of this fearture no actual recursion would occur. -- J. Giles "I conclude that there are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies and the other way is to make it so complicated that there are no obvious deficiencies." -- C. A. R. Hoare
Post Follow-up to this messageJames Giles wrote: (snip) > It should be noted that the word "recursive" here is a bit of a > misnomer. The I/O is not really being done recursively, but on > some iomplementations you are doint something that may require > the I/O library to be reentrant. > In F2003, the above does not need the "recursive" keyword > since foo does not call itself, either directly or indirectly. > However, the I/O library procedures that do internal write > *may* (depending on implementation) be calling themselves > indirectly. It's possible, though not a usual implementation, > for the call to foo to actually be made from within the I/O > library itself. In such an unusual implementation, there really > would be recursion. In most implementations of this fearture > no actual recursion would occur. In the implementations that I know, I/O statements are mulitple subroutine calls, one to initialize the I/O, specify the unit and type of operation (unformatted, formatted with a FORMAT statement, list directed, etc.), additional calls for each I/O list element, though an implied DO may be one call or a call inside a loop, and finally one to terminate the statement. To paraphrase an ex-president, it depends on your definition of 'in'. I suppose it could even be done with callback routines, but in any case the I/O routines maintain state information that can be overwritten if another I/O is started before the first is finished. -- glen
Post Follow-up to this messageglen herrmannsfeldt wrote: ... > In the implementations that I know, I/O statements are mulitple > subroutine calls, one to initialize the I/O, specify the unit and > type of operation (unformatted, formatted with a FORMAT statement, > list directed, etc.), additional calls for each I/O list element, > though an implied DO may be one call or a call inside a loop, and > finally one to terminate the statement. That's the usual implemenation I see too. It's the way I implemented it when I wrote an I/O support library for Fortran on CTSS. Notice that none of the I/O routines actually call themselves, either directly or indirectly, if so-called recursive I/O is performed. But, what does happen (unless you independently identify each I/O sequence - which is what I did) is that a second initialization call occurs before the first sequence of calls is terminated. This could even go further - the second sequence could intigate still a third I/O sequence, and so on. It's possible to handle all this correctly (I did). You can even allow I/O to external units and not just distinct internal files and still get it all straight. I limited it to distinct external units - nesting I/O sequences that use the same I/O unit was too hard (for me anyway). -- J. Giles "I conclude that there are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies and the other way is to make it so complicated that there are no obvious deficiencies." -- C. A. R. Hoare
Post Follow-up to this messageHi again, thanks to all who answered. It is a kind of pity that this oversight slipped through the F95 standard, but I have to live with it now. I have rewritten my code so that the function is replaced by a subroutine, so that the result of the conversion cannot be accidentally used directly in an I/O statement. It is correct that the RECURSIVE keyword was nonsense in the posted example. I was playing around to find a way to trick the compiler into giving a warning message for the code which apparently has a side effect. And PURE did not suffice. Neither does ELEMENTAL (which of course is even more different from what I really want), which implies PURE. So while my code was not F95 conforming, the lack of warnings could by considered only a quality-of-implementation issue. -- Cheers, -ha
Post Follow-up to this messagePowered by vBulletin
Copyright 2000-2006 Jelsoft Enterprises Limited.