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

Variable Format Expressions Not Allowed in Fortran 2018

SunMesa
Beginner
1,222 Views

When checks for Fortran 2018 compatibility are turned on, I see that variable format expressions, e.g., statements like Write(2,'(<NMassBins>F10.3)')NDat, are no longer allowed. I personally thought this was a pretty handy feature, but in any case, what is the suggested alternative to get the same effect? Thanks for any info!

0 Kudos
1 Solution
Steve_Lionel
Honored Contributor III
1,219 Views

The "unlimited repeat count" feature from F2008 is often a good substiute. If nothing else, you can write a format into a character variable and use the variable as your format.

View solution in original post

0 Kudos
8 Replies
Steve_Lionel
Honored Contributor III
1,220 Views

The "unlimited repeat count" feature from F2008 is often a good substiute. If nothing else, you can write a format into a character variable and use the variable as your format.

0 Kudos
SunMesa
Beginner
1,206 Views

Thanks Steve, the unlimited repeat count worked. I replaced

Write(2,'(<NMassBins>F10.3)')NDat

with

Write(2,'(*(F10.3))')NDat

and the compiler was happy. I thought I'd try your second option (construct a format on the fly), and came up with this:

Integer :: NMassBins
Real, Allocatable :: NDat(:)
Character(12) :: FMT
.
NMassBins = [Some calculated integer, say N]
Allocate(NDat(N))
NDat = [Some calculated array]
.
Write(FMT,'(a2,I2,a8)') "'(", NMassBins, "(F10.3)'"
Write(2,FMT)NDat

The compiler was similarly o.k.  with that, although it's rather cumbersome, and seems problematic if I didn't know beforehand that NMassBins was no bigger than 99.

Any idea why variable format expressions are now frowned upon? They would seem to be a much cleaner method than either of the above alternatives.

0 Kudos
SunMesa
Beginner
1,194 Views

The code snippet above, although it compiles, is incorrect. It should be:

Integer :: NMassBins
Real, Allocatable :: NDat(:)
Character(11) :: FMT
.
NMassBins = [Some calculated integer, say N]
Allocate(NDat(N))
NDat = [Some calculated array]
.
Write(FMT,'(a1,I2,a8)') '(', NMassBins, '(F10.3))'
Write(2,FMT)NDat

This code compiles and executes correctly, and produces identical results to the 'unlimited repeat' method above. Same question though, why is the (to me, anyway) more explicit and more readable/intuitive method of variable format expression now out of favor? In any case, I've flagged this as solved, thanks Steve!

0 Kudos
GVautier
New Contributor II
1,181 Views

Instead of

Write(FMT,'(a2,I2,a8)') "'(", NMassBins, "(F10.3)'"

use

Write(FMT,'(a2,I0,a8)') "'(", NMassBins, "(F10.3)'"

to be independent of NMassBins

0 Kudos
SunMesa
Beginner
1,152 Views

GVautier,

That's a good point, I0 formatting would produce the minimum required size when writing to the variable FMT, but then the question arises, how do you declare the size of the character variable FMT? One solution is to just make it some large value and use TRIM(FMT) in the write statement. I've tried this and it works... not very elegant, but effective.

0 Kudos
FortranFan
Honored Contributor II
1,143 Views

Not sure how any group of people can even define elegance, let alone hope to succeed in bringing it consistently into a language, especially one like Fortran with its long legacy.

For the kind of situations shown by OP in this thread, current standard Fortran allows the following that includes both a generic descriptor and an unlimited repeat count.  Many readers may find it good enough for their needs.

   real :: Ndat(3)
   character(len=*), parameter :: fmtg6 = "(*(g0.6,1x))"
   call random_number( Ndat )
   print fmtg6, "Ndat: ", Ndat
end

Output can be:

Ndat:  .392087E-06 .254804E-01 .352516
0 Kudos
Steve_Lionel
Honored Contributor III
1,139 Views

Variable Format Expressions (VFEs) were a DEC invention from the PDP-11 era. They were carried forward into VAX FORTRAN, DEC Fortran and then Intel Fortran. Other vendors cursed us as VFEs are un-Fortran-like and difficult to implement properly, but customers liked them and so some vendors broke down and put them in. In most cases where VFEs were used, unlimited repeat works well, but one can construct more complex cases where it doesn't. For that there's run-time formats, which ARE standard.

0 Kudos
andrew_4619
Honored Contributor II
1,166 Views

"Any idea why variable format expressions are now frowned upon? "

That has never been part of standard Fortran it is a vendor extension. Intel chose to support it but if you choose also standards checking you will get errors/warnings. The extension is not needed anyway as other standard confirming methods can be used as illustrated in this thread.

0 Kudos
Reply