Simplest Fortran Code Still Has an Error - fortran

I'm learning Fortran for a new job and started writing some very, very basic programs. To compile, I'm using gcc version 4.6.2, and I'm working on Linux Suse OS (if that matters at all). I believe the version of Fortran I'm using is F90 or F95. The code is written using the VIM text editor.
Here is the program I've written
INTEGER, PARAMETER :: x = 2, y = 3
INTEGER :: z = x+y
print *, z
That's it! Oh, and the lines are indented, They start on column 8, so indentation isn't an issue.
UPDATE 1
I have tried doing this like so:
PROGRAM print_stuff
print *, z
END PROGRAM print_stuff
I also tried adding the IMPLICIT NONE statement to all of that and didn't get a change in the error.
END UPDATE 1
I save, quit, and compile. The compiler returns this error:
Error: Unexpected end of file in 'practice1.f'
Anyone know what the problem is? I've even tried removing the print statement and just having the variable declarations but the same error occurs. It's keeping me from practicing Fortran at all!

Your first version
INTEGER, PARAMETER :: x = 2, y = 3
INTEGER :: z = x+y
print *, z
is NOT a valid Fortran program. Every valid program ends with the end statement. A 'program' without an end statement is not syntactically correct. Keep reading your introductory tutorial.
I suggest you get into the habit of starting your programs with a program statement, with a name, such as
program myprog
and ending them with
end program myprog
Strictly, neither the program statement nor a program name is necessary but they do make things look a bit more comprehensible.
Oh, and while I'm writing ... don't get into the habit of starting lines at column 8, that smacks of the now out-dated fixed-form source. If you are using a reasonable compiler (such as gcc) give your filenames the .f90 suffix and let your source code run free. All the while observing good habits of indentation of course.
EDIT in response to OP's edits
PROGRAM print_stuff
print *, z
END PROGRAM print_stuff
and
INTEGER, PARAMETER :: x = 2, y = 3
INTEGER :: z = x+y
print *, z
END
are both syntactically correct. Both gfortran (v4.1.2) and Intel Fortran (v13.0.1) compile both correctly and produce executables which execute.

Related

How to resolve "unclassifable error statement" in Fortran [duplicate]

I'm very new at Fortran. I'm trying to compile this Fortran, I think 90??? Code. I'm using visual studio with the intel compiler.
The following code is giving me an error 5082. I have absolutely no idea why. Like literally no clue. Please, please help.
integer function Dub(n)
integer n
Dub = 2*n
return
end
program Subroutines
implicit none
! Variables
integer n
n = 5
! Body of Subroutines
write(*,*) n
Dub(n)
write(*,*) 'Press Enter to Exit'
read(*,*)
stop
end program Subroutines
In Fortran a call to a function, or a subroutine, must be part of a statement (or an initialization expression, but that's more advanced). name(argument[s]) by itself is not a statement, unlike some other languages such as C, C++ and Java. A function call must be in an expression, and a subroutine call must use the call keyword. See https://en.wikibooks.org/wiki/Fortran/Fortran_procedures_and_functions for examples.
Changing that line of your program to n = Dub(n) would make it legal, but rather useless. That function does nothing except return a value, and your main program does nothing useful with the value returned. Generally you call a function because you want either a side effect from executing the function, or to use the returned value, or both.

Fortran Basic Conditional and Loop Code Errors

I'm doing a very basic Fortran tutorial to learn it for grad school and I input the codes for conditionals and loops exactly as they were written in the tutorial but I keep getting the "unexpected end of file" error when I try to compile with gfortran.
This is my conditional code:
if (angle < 90.0) then
print *, 'Angle is acute'
else if (angle < 180.0) then
print *, 'Angle is obtuse'
else
print *, 'Angle is reflex'
end if
This is my loop code:
integer :: i
do i=1,10,2
print *, i ! print odd numbers
end do
Both of them are completed with end statements, so I'm not sure what else it wants. I've only just started teaching myself today, so I'm still just copying codes verbatim from the tutorial and not sure how to troubleshoot anything.
In the tutorial you are following the pieces of code shown are not complete programs. They cannot be compiled as they are.
You will see this frequently, especially in answers on this site.
The code fragments shown miss a lot of context to make clear the parts that are to be taught. That's perhaps a little unfortunate, but Fortran is quite a verbose language, and so there's a trade-off for clarity.
For a complete program you've possibly seen that "all programs must have an end statement to complete them". You may think that the end if and end do statements are suitable for this. They are not: you need an end program statement. The following are two minimal programs:
end
and
end program
(There are also forms with a program statement.)
That is:
if (.true.) then
print *, "Hello, world!"
end if
end program
is compilable if and only if that last line exists.
Further, things like implicit none and variable declarations and definitions would be part of the implied context of example fragments.
If you are just learning and want to try code start with the following skeleton
program test
implicit none
<variable declarations>
<program code>
stop
contains
<function definitions>
end program
The above structure should be enough for most one use programs (write a program to do one thing). The stop above isn't required, it just makes it clear to see where the program instructions actually end.
If you want to use standard numeric types include the iso_fortran_env before the implicit none statement
program test
use, intrinsic :: iso_fortran_env
implicit none
the above will allow you to define integer(int32), integer(int64), real(real32), real(real64), etc.

Fortran :: Syntax error in OPEN statement at (1)

I was trying to test my cryptography algorithm by [diehard tests] (http://stat.fsu.edu/pub/diehard/), that I realized my input file must be an unformatted and direct access file.
So I tried to write a simple program in Fortran to read from a file and write it to another.
First of all, is it the only way to make an unformatted or direct access file ?
If it is so, I've got this Error
open(unit=2, file='unf.BIN',RECL=rl , form='UNFORMATTED', access='direct')
1
Error: Syntax error in OPEN statement at (1)
I use RECL because of some missing RECL parameter in Open statement errors.(Fortran 90, Compiling program: Error messages)
Here is my Fortran code:
program BinaryWriter
implicit none
integer :: i
integer :: p
open(unit=1,file='encout')
open(unit=2, file='unf.BIN',RECL=rl , form='UNFORMATTED', access='direct')
do i=1 ,256
read (8,'(i1)') p
write(*,*) p
end do
close(1)
close(2)
end program BinaryWriter
Two things:
1) Please stop using unit numbers less than 10. Virtually all modern Fortran compilers do now have the newunit identifier, which, instead of the old unit actually picks an unused value, so always use a variable there. But even if you want to use unit, set it to a value of 10 or more.
2) For direct access, the program needs the record length. So if you have access="direct", you also need an recl=<some integer value> to tell the compiler where a new record starts.
Now in your case, you have a RECL=rl entry in the open statement, but I can't see what rl is. It needs to be a positive integer.
Edit to add: As #IanH pointed out in a comment below your question, it is possible that you are using fixed form fortran. This might be caused by the file extension of your source code file being .f or .f77. In that case, you'd have to wrap your lines manually:
program dir
implicit none
integer :: rl
open(unit=20, file='delme.bin', recl=<the record length>,
& form='unformatted', access='direct')
close(20)
end program dir
Note that the & is in the 6th position of the line. Fortran 77 code usually uses a + there, but & is also compatible with newer Fortran versions, that's why I prefer it. F77 standard is just any character in that 6th spot.

End of Record error when saving a variable

I'm having a runtime error when I run a code that works without problems using a different computer.
I'm wondering if the problem is the Fortran compiler of this machine (GCC 4.9.2) since the former computer used a previous version.
The issue comes when defining a variable like this:
In a module I define
character(30),allocatable,save :: sceneclass(:)
Then in the subroutine sceneclass is defined according to
character(30) surf, frac, scene
allocate(sceneclass(10))
do i=1,10
write(sceneclass(i),*) trim(scene)//trim(surf)//'_'//trim(frac)
enddo
In the first iteration I get the "End of record". But I don't know where is the problem. It seems to work fine in other computers.
You are probably writing a string to sceneclass(i) that is longer then the 30 chars you specified.
I can reproduce this with
program test
implicit none
character(10),allocatable :: sceneclass(:)
integer :: i
allocate( sceneclass(10) )
do i=1,10
write(sceneclass(i),*) 10**i
enddo
print *, ( trim(sceneclass(i)), i=1,10 )
end program
gfortran fails with
Fortran runtime error: End of record
while ifort reports the error correctly:
output statement overflows record, unit -5, file Internal List-Directed Write
Increasing the string length to 12 solves the issue in this case. You can (and should) use iostat within the write statement to capture this.
One thing to be aware of, when you specify a list directed * write of a character string, the compiler always(?) adds an extra lead blank, so the effective length of the string you can write is one less than you might expect.
To remedy that (and of course assuming you don't want the lead blank anyway ) use a string edit descriptor:
write(sceneclass(i),'(a)')...
Interestingly ifort (linux 11.1) actually allows you to overrun by one character:
character*5 c
write(c,*)'12345' ! result: " 1234"
which I would consider a bug. It seems they forgot to count the blank too.. ( gfortran throws the above error on this, and ifort balks if you add one more character )
see here if you wonder why the blank.. Are Fortran control characters (carriage control) still implemented in compilers?
and now I'm curious if some compiler somewhere didn't do that for an internal list write, or maybe your code was previously compiled with a flag to disable the "printer control" code

In fortran, can I type function?

I want make a function as I type and read it as a function. For example, if I type x+y, then f(x,y)=x+y. Is this possible? The following code does not work.
real function f(x,y)
real x,y
write(6,*) "type f(x,y)"
read*, f
return
end
Yes, you can, but your syntax is a bit off.
PROGRAM READFUNC
REAL x,y,F,res
res = F(x,y)
WRITE(*,*) res
END
REAL FUNCTION F(x,y)
REAL x,y
WRITE (*,*) "Type in"
READ (*,*) F
RETURN
END
note that I compiled this w/ gfortran so I'm not sure if it uses any F90+ extensions or not.
EDIT After reading your edits, I see that this isn't what you want; you want some kind of eval/parser. In general this is not a trivial thing. You're going to have to do some kind of token parsing work.
However there are libraries that can do this for you that are already written.
See this article for an example of where to look for more research.
F(X,Y)=X+Y
99 READ(*,*)X,Y
WRITE(*,*)F(X,Y)
GO TO 99
You enter 3 4 or 3,4 and you get out 7