Fortran IIFIX unknown symbol - fortran

I have an old fortran code compiling nice using GFORTRAN.
But when I try to call a function I'm getting the follow error:
undefined symbol: iifix
I've found 3 occurrences of this function in the code, all of them in same context:
(some blah blah blah)
INTEGER*2 IWAH(24)
real*4 AH(9000)
(more blah blah blah)
iwah (3) = iifix (ah (3))
(and the blah blah blah continues...)
Searching for "IIFIX" I've found only "IFIX()" to convert real numbers to integer. This makes some sense to me because the variables format fits in the function purpose but .... I don't know. I have no idea what I'm doing....
How can I safely replace this function?
or ... how can I fix this error?
I'm using gfortran and my code ends with ".f90"

First, integer*2 and real*4 are not portable. I'll ignore that issue. What you likely want is to change iifix(ah(3)) to int(ah(3),2)

Related

`Unexpected element ‘\’ in format string` in code written for MS Fortran [duplicate]

I have a project written in VS2010 with Intel Visual Fortran. I have a dump subroutine to write a 2D matrix into file:
subroutine Dump2D(Name,Nx,Ny,Res)
implicit none
integer i,j,Nx,Ny
real(8) :: Res(Nx,Ny)
character(len=30) name,Filename
logical alive
write(filename,*) trim(Name),".dat"
Write(*,*) "Saving ",trim(Name)," Please wait..."
open (10,file=filename)
do i=1,Ny
Write(10,FMt="(D21.13\)") (Res(j,i),j=1,Nx)
Write(10,*)
end do
close(10)
Write(*,*) "Save ",trim(Name),"Complete!"
return
end subroutine Dump2D
It is ok to compile and run. But when I compile in emacs using gfortran it gives me the error:
I think it's because the gfortran doesn't recognize \ in a format for a write command. How do I fix this problem?
Write(10,FMt="(D21.13\)") (Res(j,i),j=1,Nx)
1
Error: Unexpected element '\' in format string at (1)
The edit descriptor \ relates to backslash editing. This is a non-standard extension provided by the Intel compiler (and perhaps others). It is not supported by gfortran.
Such backslash editing is intended to affect carriage control. Much as in this answer such an effect can be handled with the (standard) non-advancing output.1
As you simply want to output each column of a matrix to a record/line you needn't bother with this effort.2 Instead (as you'll see in many other questions):
do i=1,Ny
write(10,fmt="(*(D21.13))") Res(:,i)
end do
There are also other approaches which a more general search will find.
1 The Intel compiler treats \ and $ in the same way.
2 There are subtle aspects of \, but I'll assume you don't care about those.
Another approach (although francescalus answer is better in your case) would be to build a format string that contains the number of elements to include in your row. One way of doing this is to use the following to build the format string (which uses an explicit space character to separate elements within a line in the file):
WRITE(fmtString, '(A,I0,A)') '(', Nx, '(D21.13,:,1X))' *
Then use the format string variable in your WRITE statement as so:
do i=1,Ny
Write(10,FMt=fmtString) (Res(j,i),j=1,Nx)
end do
This approach can also be very useful if you want to use something other than spaces to separate elements (e.g. commas or semicolons).
*As that's a little difficult to read, I will provide an example. For Nx = 3, this would be equivalent to:
fmtString = '(3(D21.13,:,1X))'
Which is 2 numbers formatted using D21.13, each followed by a space, and a final number formatted using D21.13, but without a space after it (as the ":" stops at the final item).
The backslash is not valid in Fortran 77 FORMAT statements. Gfortran will not compile it, unless you fix the code. There is no flag that will change that AFAIK (-fbackslash should not help here).
If I understand the intention correctly (and I may be wrong), the backslash does the same as the dollar sign in some other compilers and prevents terminating a record (line). In that case the advance="no" put in the write statement should help. It is Fortran 90, but you should not avoid it just for that reason.

gfortran error: unexpected element '\' in format string at (1)

I have a project written in VS2010 with Intel Visual Fortran. I have a dump subroutine to write a 2D matrix into file:
subroutine Dump2D(Name,Nx,Ny,Res)
implicit none
integer i,j,Nx,Ny
real(8) :: Res(Nx,Ny)
character(len=30) name,Filename
logical alive
write(filename,*) trim(Name),".dat"
Write(*,*) "Saving ",trim(Name)," Please wait..."
open (10,file=filename)
do i=1,Ny
Write(10,FMt="(D21.13\)") (Res(j,i),j=1,Nx)
Write(10,*)
end do
close(10)
Write(*,*) "Save ",trim(Name),"Complete!"
return
end subroutine Dump2D
It is ok to compile and run. But when I compile in emacs using gfortran it gives me the error:
I think it's because the gfortran doesn't recognize \ in a format for a write command. How do I fix this problem?
Write(10,FMt="(D21.13\)") (Res(j,i),j=1,Nx)
1
Error: Unexpected element '\' in format string at (1)
The edit descriptor \ relates to backslash editing. This is a non-standard extension provided by the Intel compiler (and perhaps others). It is not supported by gfortran.
Such backslash editing is intended to affect carriage control. Much as in this answer such an effect can be handled with the (standard) non-advancing output.1
As you simply want to output each column of a matrix to a record/line you needn't bother with this effort.2 Instead (as you'll see in many other questions):
do i=1,Ny
write(10,fmt="(*(D21.13))") Res(:,i)
end do
There are also other approaches which a more general search will find.
1 The Intel compiler treats \ and $ in the same way.
2 There are subtle aspects of \, but I'll assume you don't care about those.
Another approach (although francescalus answer is better in your case) would be to build a format string that contains the number of elements to include in your row. One way of doing this is to use the following to build the format string (which uses an explicit space character to separate elements within a line in the file):
WRITE(fmtString, '(A,I0,A)') '(', Nx, '(D21.13,:,1X))' *
Then use the format string variable in your WRITE statement as so:
do i=1,Ny
Write(10,FMt=fmtString) (Res(j,i),j=1,Nx)
end do
This approach can also be very useful if you want to use something other than spaces to separate elements (e.g. commas or semicolons).
*As that's a little difficult to read, I will provide an example. For Nx = 3, this would be equivalent to:
fmtString = '(3(D21.13,:,1X))'
Which is 2 numbers formatted using D21.13, each followed by a space, and a final number formatted using D21.13, but without a space after it (as the ":" stops at the final item).
The backslash is not valid in Fortran 77 FORMAT statements. Gfortran will not compile it, unless you fix the code. There is no flag that will change that AFAIK (-fbackslash should not help here).
If I understand the intention correctly (and I may be wrong), the backslash does the same as the dollar sign in some other compilers and prevents terminating a record (line). In that case the advance="no" put in the write statement should help. It is Fortran 90, but you should not avoid it just for that reason.

FORTRAN WRITE in one line only (prevent newline or carriage returns) [duplicate]

I have noticed the results of list-directed output write(*,*) in Fortran is compiler dependent.
Indeed, with the code:
program one
real(8), dimension(5):: r1
do i=1,5
r1(i)=sqrt(i*10.0)
end do
write(*,*) (r1(i), i =1,5)
end program one
intel compiler ifort gives standard output broken by a newline:
3.16227769851685 4.47213602066040 5.47722530364990
6.32455539703369 7.07106781005859
while gfortran gives the equivalent one line result:
3.1622776601683795 4.4721359549995796 5.4772255750516612 6.3245553203367590 7.0710678118654755
I think that ifort is writing maximum 3 items per line (when floating real numbers).
Is there any way to make the ifort output be like gfrotran, i.e. avoid the newline?
Ideally, I would like to keep list-directed output (*,*) instructions, so I am looking for something like a compiler option or so, if any.
Since verson 14, intel fortran compiler has the wrap-margin function. By default, the record is wrapped after 80 characters. For disabling this restriction, you should specify:
on Linux: -no-wrap-margin
on WIndows: /wrap-margin-
See more on Intel Fortran's reference guide
No. List-directed (free-format) output provides convenience, but you give up control. Various aspects of the output are unspecified and allowed to be chosen to the compiler. If you want full control, you have to use formatted output.
Look into edit descriptors in your favorite Fortran book or online documentation. You can use fmt specifier in the write statement to specify edit descriptors. For example:
write(*,fmt='(5(F6.4,3X))') (r1(i), i =1,5)
should output something similar to:
3.1623 4.4721 5.4772 6.3246 7.0711
See https://software.intel.com/en-us/forums/topic/401555
Specify FORT_FMT_RECL or use
write (,"(G0,1X))"

Old FORTRAN Namelist Compiler (gfortran) Flag?

I'm currently in the process of upgrading an old program written in FORTRAN and I'm trying to get it to compile using gfortran. I can get it to build, however the program now chokes on the namelists that it is reading in.
An example of a namelist that came with the program is shown below. It cannot correctly read this file due to the space between the variable name and the parenthesis. Since these files are very large, is there anyway I can tell gfortran to expect an older namelist format?
&<NAME>
<VARNAME> (1) = 0,
<VARNAME> (2) = -1e-13,
<VARNAME> (3) = 0.2983
&End
If not, I can resort to doing a search/replace but I'd rather not mess with the data and just have the code successfully read it in.
Namelist is quite complicated, as you can tell from the fact that there are 92 namelist test cases in the gfortran testsuite.
gfortran has no option to do what you ask. You will probably have to remove the blanks by hand or by sed, like Vladimir F suggested.
I might add that blanks in the subobject designator (the varname(i) part) are explicitly forbidden in the F2003 standard 10.10.1.1:
"In the input record, each object name or subobject designator may be preceded and followed by one or more optional blanks but shall not contain embedded blanks."
so this is unlikely to be changed in a future version of gfortran.

Fortran return statement

I'm trying to get some code compiled under gfortran that compiles fine under g77. The problem seems to be from a return statement:
ffuncs.f:934.13:
RETURN E
1
Error: Alternate RETURN statement at (1) requires a SCALAR-INTEGER return specifier
In the code anything E was specified as real*8:
IMPLICIT REAL*8 ( A - H , O -Z )
However, E was never given a value or anything in fact you never see it until the return statement. I know almost nothing about fortran. What is the meaning of a return statement with an argument in fortran?
Thanks.
In FORTRAN (up to Fortran 77, which I'm very familiar with), RETURN n is not used to return a function value; instead, it does something like what in other languages would be handled by an exception: An exit to a code location other than the normal one.
You'd normally call such a SUBROUTINE or FUNCTION with labels as arguments, e.g.
CALL MYSUB(A, B, C, *998, *999)
...
998 STOP 'Error 1'
998 STOP 'Error 2'
and if things go wrong in MYSUB then you do RETURN 1 or RETURN 2 (rather than the normal RETURN) and you'd be hopping straight to label 998 or 999 in the calling routine.
That's why normally you want an integer on that RETURN - it's not a value but an index to which error exit you want to take.
RETURN E sounds wrong to me. Unless there's a syntax I'm unaware of, the previous compiler should have flagged that as an error.
In a Fortran function one returns the value, by assigning the value to a fake variable which is the same name as the function. Once you do that, simply return.
I think #Carl Smotricz has the answer. Does argument list of ffuncs has dummy arguments that are asterisks (to match the asterisk-label in the calls)? Or was this used without there being alternative returns? If there were no alternative returns, just delete the "E". If there are alternative returns, the big question is what the program was doing before at run time since the variable was of the wrong type and uninitialized. If the variable didn't have an integer value matching one of the expected branches, perhaps the program took the regular return branch -- but that's just a guess -- if so, the easy fix is to again to delete the "E".
The "alternate return" feature is considered "obsolescent" by the language standard and could be deleted in a future standard; compilers would likely continue to support it if it were removed because of legacy code. For new code, one simple alternative is to return an integer status variable and use a "select case" statement in the caller.