Error in implicit declaration in Fortran - fortran

I have checked all the formats of the implicit type declaration but have not been able to find out the error in the following line . I have been running the code using f77 to compile this.
implicit real*4 (a-h,o-z)
while running the program it gives the following error for the above statement.
implicit real*4 (a-h,o-z)
1
Error: Unexpected character in variable list at (1)

A few basic rules if you are using F77 or earlier versions.
Put the implicit line first
Columns 1-5 are for labels
Column 6 is for continuation
Start the code in column 7
The code should not go past column 72. Some compilers have an option to extend the line length to 80 or 120 or 132 (widths of line printers when F77 first came out)
If you wish to use free format, use one of the later versions of fortran

Related

Code with syntax error in do loop compiles and gives wrong result

Here is the source (lets call it test4.F):
do 10 i=1
write(*,*) i
10 continue
end
With gfortran:
$gfortran test4.F
$./a.out
-259911288
with ifort:
$ifort test4.F
$./a.out
0
I know the syntax is incorrect. So both should throw compile-time errors.
Your test program is indeed not valid Fortran, but there isn't a syntax problem.
When the file has a .F suffix both gfortran and ifort assume that the program uses fixed form source. In fixed form source, blanks in statements aren't significant (outside character contexts). Your program is equivalent to:
do10i=1
write(*,*) i
10 continue
end
With comments:
do10i=1 ! Set the real variable do10i to value 1
write(*,*) i ! Write the undefined integer variable i
10 continue ! Do nothing
end ! End execution
Because of implicit typing you have a defaul real variable do10i and so there isn't a syntax error for a do control, and there isn't a do control that sets i to 1.
Instead your program is invalid because you are referencing the value of i although it hasn't first been defined (because it isn't a loop variable). But this isn't an error the compiler has to complain about at compile time (or even run time). A compiler is allowed to print any value it likes. gfortran chose one, ifort another.
Liberal use of implicit none and avoiding fixed-form source are good ways to avoid many programming errors. In this case, use of an end do instead of continue would also alert the compiler to the fact that you intended there to be some looping.
Which version of gfortran are you using? With gfortran-6, the following
PROGRAM MAIN
USE ISO_FORTRAN_ENV, ONLY:
1 COMPILER_VERSION,
2 COMPILER_OPTIONS
C EXPLICIT TYPING ONLY
IMPLICIT NONE
C VARIABLE DECLARATIONS
INTEGER I
DO 10 I = 1
WRITE (*,*) I
10 CONTINUE
PRINT '(/4A/)',
1 'THIS FILE WAS COMPILED USING ', COMPILER_VERSION(),
2 ' USING THE OPTIONS ', COMPILER_OPTIONS()
END PROGRAM MAIN
indeed throws the error
main.F:13:13:
DO 10 I = 1
1
Error: Symbol ‘do10i’ at (1) has no IMPLICIT type
I suspect that test4.F does not include the implicit none statement. Consequently, DO 10 I = 1 is interpreted as an implicitly defined real variable DO10I = 1. Here is a sample of a fixed form statement showing what are now (post Fortran 90) considered significant blanks followed by an equivalent statement without the blanks
DO I=1 , M AX ITER S
DO I = 1 , MAXITERS
Upshot, always use explicit variable declarations in all your programs. Better yet, only write Fortran in free source form main.f90. Free source form is more compatible with modern interactive input devices than fixed form. The maximum line length is 132 characters, compared to the older limit of 72 characters. This reduces the possibility of text exceeding the limit, which could lead the compiler to misinterpret names. Here's the same code in free source form
program main
use ISO_Fortran_env, only: &
stdout => OUTPUT_UNIT, &
compiler_version, &
compiler_options
! Explicit typing only
implicit none
! Variable declarations
integer :: i
do i = 1, 3
write (stdout, *) i
end do
print '(/4a/)', &
' This file was compiled using ', compiler_version(), &
' using the options ', compiler_options()
end program main
and
gfortran-6 -std=f2008ts -o main.exe main.f90
./main.exe
yields
1
2
3
This file was compiled using GCC version 6.1.1 20160802 using the options -mtune=generic -march=x86-64 -std=f2008ts

Unexpected Statement Function at 1 in Fortran

I am new to Fortran and writing this small program to write out 100 ordered pairs for a circle.
But I get the error mentioned above and I don't know how to resolve.
implicit real*8(a-h,o-z)
parameter(N=100)
parameter(pi = 3.14159265358979d0)
integer*8 k
dtheta=2*pi/N
r=1.0d0
x00=0.0d0
y00=0.0d0
do k=0,N-1
xb(k)=r*cos(k*dtheta)-x00
yb(k)=r*sin(k*dtheta)-y00
enddo
open(64,file='xbyb.m',status='unknown')
write(64,*) (xb(k),k=0,N-1),(yb(k),k=0,N-1)
close(64)
end
You do not declare the arrays xb and yb.
Although not technically FORTRAN 77 I still suggest using implicit none or at least an equivalent compiler option to be forced to declare everything explicitly. Implicit typing is evil and leads to bugs.
As High Performance Mark reminds, the syntax
f(k) = something
declares a feature (now obsolescent in Fortran 95 and later) called a statement function. It declares a function of one argument k. The only way for the compiler to recognize you mean an array reference instead is to properly declare the array. The compiler complains the statement function is unexpected because the declaration must be placed before the executable statements.
Your implied do loop in the write statement is Fortran 90 anyway, so no need to stick to FORTRAN 77 in the 21st century.
Other tips:
status='unknown' is redundant, that is the default, just leave it out.
You can just write r = 1 and x00 = 0.

Fortran 90 read file

I am getting my hands wet with Fortran, and am wanting to read a txt file into a an array. I feel like I have tried everything. The txt file is comma seperated 11 rows with 1 number on each row.
Here is my code
program test
real:: obs1,i,jj,count,x_1
real,allocatable:: x(:)
open(1,file='data1.txt',status='old',action='read')
read(1,*) obs1
allocate(x(obs1))
do i=1, obs1
read(1,*) x_1
x(i)=x_1
end do
do jj=1, obs1
print*,x(jj)
end do
end program test
this is the error I am receiving:
The highest data type rank permitted is INTEGER(KIND=8)
This statement
allocate(x(obs1))
contains an error, though I'm not sure it's the one that matches the error message you report. obs1 is a real variable, but array dimensions (and indices) have to be integers. Change the declaration of obs1 to
integer :: obs1
Your compiler ought to complain about using a real variable in the do loop control too, do i=1, obs1. Again, use an integer.
As an aside, since you are new to Fortran, learn to use implicit none in every scope within your programs. SO will provide many questions and answers to explain what it means and why it is important, so will any of your favourite Fortran tutorials.

fortran77 to fortran90 differences in output

I have downloaded the following fortran program dragon.f at http://www.iamg.org/documents/oldftp/VOL32/v32-10-11.zip
I need to do a minor modification to the program which requires the program to be translated to fortran90 (see below to confirm if this is truly needed).
I have managed to do this (translation only) by three different methods:
replacing comment line indicators (c for !) and line continuation
indicators (* in column 6 for & at the end of last line)
using convert.f90 (see https ://wwwasdoc.web.cern.ch/wwwasdoc/WWW/f90/convert.f90)
using f2f.pl (see https :// bitbucket.org/lemonlab/f2f/downloads)
Both 1) and 3) worked (i.e. managed to compile program) while 2) didn't work straight away.
However, after testing the program I found that the results are different.
With the fortran77 program, I get the "expected" results for the example provided with the program (the program comes with an example data "grdata.txt", and its example output "flm.txt" and "check.txt"). However, after running the translated (fortran90) program the results I get are different.
I suspect there are some issues with the way some variables are declared.
Can you give me recommendations in how to properly translate this program so I get the exact same results?
The reason I need to do it in fortran90 is because I need to input the parameters via a text file instead of modifying the program. This shouldnt be an issue for most of the parameters involved, except for the declaration of the last one, in which the size is determined from parameters that the program does not know a priori (see below):
implicit double precision(a-h,o-z)
parameter(lmax=90,imax=45,jmax=30)
parameter(dcta=4.0d0,dfai=4.0d0)
parameter(thetaa=0.d0,thetab=180.d0,phaia=0.d0,phaib=120.d0)
dimension f(0:imax,0:jmax),coe(imax,jmax,4),coew(4),fw(4)
So for example, I will read lmax, imax, jmax, dcta, dfai, thetaa, thetab, phaia, and phaib and the program needs to declare f and coe but as far as I read after googling this issue, they cannot be declared with an unknown size in fortran77.
Edit: This was my attempt to do this modification:
character fname1*100
call getarg(1,fname1)
open(10,file=fname1)
read(10,*)lmax,imax,jmax,dcta,dfai,thetaa,thetab,phaia,phaib
close(10)
So the program will read these constants from a file (e.g. params.txt), where the name of the file is supplied as an argument when invoking the program. The problem when I do this is that I do not know how to modify the line
dimension f(0:imax,0:jmax)...
in order to declare this array when the values imax and jmax are not known when compiling the program (they depend on the size of the data that the user will use).
As has been pointed out in the comments above, parameters cannot be read from file since they are set at compile time. Read them in as integer, declare the arrays as allocatable, and then allocate.
integer imax,jmax
real(8), allocatable :: f(:,:),coe(:,:,:)
read(10,*) imax,jmax
allocate(f(0:imax,0:jmax),coe(imax,jmax,4))
I found out that the differences in the results were attributed to using different compilers.
PS I ended up adding a lot more code than I intended at the beginning to allow reading data from netcdf files. This program in particular is really helpful for spherical harmonic expansion. [tag:spherical harmonics]

Fortran compile error

I tried to compile a fortran program for soil-plant-atmosphere model, but I can't compile it under Ubuntu, it keeps giving me the error message like this:
f77 -c -o o/cupin2.o src/cupin2.f
src/cupin2.f: In subroutine `reflt':
src/cupin2.f:742:
dimension tairgl,eairgl,windgl,psisgl,hsoil,ecpy,hcpy
^
Invalid form for DIMENSION statement at (^)
make: ***
[o/cupin2.o] Error 1
Can anyone help me with this. Thanks.
Complete source code is here:Source Code
The DIMENSION statement is used to dimension arrays - so you have to specify the array dimensions. For example:
dimension tairgl(100),eairgl(20,50), ...
You don't actually need the DIMENSION statement, however, you could also say something like:
real tairgl(100)
integer eairgl(20,50)
You don't say whether this is your edit or whether someone else has written the code. The DIMENSION statement is described in:
http://en.wikipedia.org/wiki/Fortran_language_features
for example:
INTEGER, DIMENSION(0:100, -50:50) :: map
It expects array bounds after it. It's rather outdated and normally replaced by the type (e.g. REAL and the array bounds).
If you have inherited the code (and if it's got a long history) it's possible it has some syntax which is now non-standard but still compiles on some machines. If you are actively editing the code you will need to learn some FORTRAN.
UPDATE from a previous question the OP appears to have deleted the array bounds from a syntactically correct dimension statement.