Allocatable arrays in fortran 77 and gfortran - fortran

I'm trying to compile some old fortran77 programs with gfortran and getting error with allocatable arrays.
If I define arrays in f90-style, like:
REAL*8,allocatable::somearray(:)
everything is fine, but in those old programs arrays defined as:
REAL*8 somearray[ALLOCATABLE](:)
which cause gfortran error output:
REAL*8,allocatable::somearray[ALLOCATABLE](:)
1
Fatal Error: Coarrays disabled at (1), use -fcoarray= to enable
I really wish to avoid rewriting whole programs to f90 style, so, could you please tell me, is there any way to force gfortran to compile it?
Thanks a lot.

For standard checking you can use -std flag
-std=std
Specify the standard to which the program is expected to conform, which may be one of f95',f2003', f2008',gnu', or `legacy'.
To "force" gfortran to compile your code, you have to use syntax it recognizes

I'd probably go for search and replace. For example,
sed 's/\(REAL\*8\)[[:blank:]]\+\([^[]\+\)\[ALLOCATABLE\]\(.*\)/\1, allocatable :: \2\3/' <old.source> > <new.source>
where sed is available.
Of course, be careful with sed :).
In any case, as it seems your code was written in some non-standard version of old
Fortran, you'll probably need to make changes in any case.

For what it's worth the Intel Fortran compiler (v13.something) compiles the following micro-program without complaint. This executes and writes 10 to the terminal:
REAL*8 somearray[ALLOCATABLE](:)
allocate(somearray(10))
print *, size(somearray)
end
Given the history of the Intel compiler I suspect that the strange declaration is an extension provided by DEC Fortran, possibly an early implementation of what was later standardised in Fortran 90.

Related

gfortran does not allow character arrays with varying component lengths

See the example below
program test
character(10),dimension(5):: models = (/"feddes.swp", "jarvis89.swp", "jarvis10.swp" , "pem.swp", "van.swp"/)
end
The following error is returned:
Different CHARACTER lengths (10/12) in array constructor at (1)
There is no error with ifort compiler. Why does it happen with gfortran and is there any way to circumvent this problem?
You have some lengths 12 in the constructor, so it may be better to use length 12.
Also, use instead
character(len=12), dimension(5) :: models = [character(len=12) :: "feddes.swp", &
"jarvis89.swp", "jarvis10.swp", "pem.swp", "van.swp"]
Possibly even better, if you have compiler support, is
character(len=*), dimension(*) :: ...
The original code is accepted by ifort but it is not standard fortran, hence the error from gfortran. If you supply the option -std to ifort it will print warnings when the compiler allows extensions such as this.

Allocatable character variables in Fortran

My code (stripped down to what I think is relevant for this question) is
PROGRAM test
IMPLICIT NONE
CHARACTER(len=37) input
CHARACTER(len=:), allocatable :: input_trim
WRITE(*,*) 'Filename?'
READ(*,*) input
ALLOCATE(character(len=LEN(TRIM(input))) :: input_trim)
input_trim=trim(input)
.
.
.
END PROGRAM test
It works fine with Intel's Fortran compiler, however gfortran gives me a couple of errors, the first one being in the line saying
CHARACTER(len=:), allocatable :: input_trim
I'm not sure which compiler is 'right' regarding the Fortran standard. Plus I don't know how to achieve what I need in a different way?! I think what I'm doing is more of a workaround anyway. What I need is a character variable containing exactly the filename that was entered with no following spaces.
EDIT: The error is "Syntax error in CHARACTER declaration".
gfortran --version gives me "GNU Fortran (GCC) 4.4.7 20120313 (Red Hat 4.4.7-3)"
EDIT 2: You're right regarding the allocate: With ifort, I don't need it. And gfortran crashes before that so maybe it doesn't need the allocate either but I cannot test this at the moment...
This
character (len=:), allocatable :: input_trim
is certainly syntactically correct in Fortran 2003. You don't say what the error that gfortran raises is, so I can't comment on why it doesn't accept the line -- perhaps you have an old version of the compiler installed.
With an up-to-date Fortran compiler (eg Intel Fortran v14.xxx) you don't need to allocate the character variable's size prior to assigning to it, you can simply write
input_trim = trim(input)
Note that
read(*,*) input_trim
won't work.
With Absoft Fortran, this compiles (haven't run with it yet):
character,dimension(:),allocatable::Line_for_IO !Metcalf,Reid,Cohen p. 107, w/mods
if(allocated(Line_for_IO)) deallocate(Line_for_IO)
allocate(Line_for_IO(7*n+40))

What do I do about a FORTRAN intrinsic that was not part of the standard?

I'm trying to get a legacy FORTRAN code working by building it from source using gfortran. I have finally been able to build it successfully, but now I'm getting an out-of-bounds error when it runs. I used gdb and traced the error to a function that uses the loc() intrinsic. When I try to print the value of loc(ae), with ae being my integer value being passed, I get the error "No symbol "loc" in current context." I tried compiling with ifort 11.x and debugged with DDT and got the same error. To me, this means that the compiler knows nothing of the intrinsic.
A little reading revealed that the loc intrinsic wasn't part of the F77 standard, so maybe that's part of the problem. I posted the definition of the intrinsic below, but I don't know how I can implement that into my code so loc() can be used.
Any advice or am I misinterpreting my problem? Because both gfortran and ifort crash in the same place due to an out of bounds error, but the function utilizing loc() returns the same large number between both compilers. It seems a bit strange that loc() wouldn't be working if both compilers shoot back the same value for loc.
Usage:
iaddr = loc(obj)
Where:
obj
is a variable, array, function or subroutine whose address is wanted.
iaddr
is an integer with the address of "obj". The address is in the same
format as stored by an LARn
instruction.
Description:
LOC is used to obtain the address of
something. The value returned is not
really useful within Fortran, but may
be needed for GMAP subroutines, or
very special debugging.
Well, no, the fact that it compiles means that loc is known by the compiler; the fact that gdb doesn't know about it just means it's just not known by the debugger (which probably doesn't know the matmult intrinsic, either).
loc is a widely-available non-standard extension. I hate those. If you want something standard that should work everywhere, c_loc, which is part of the C<->Fortran interoperability standard in Fortran2003, is something you could use. It returns a pointer that can be passed to C routines.
How is the value from the loc call being used?
Gfortran loc seems to work a bit differently with arrays to that of some other compilers. If you are using it to eg check for array copies or such then it can be better to do loc of the first element loc(obj(1,1)) or similar. This is equivalent to what loc does I think with intel, but in gfortran it gives instead some other address (so two arrays which share exactly the same memory layout have different loc results).

fortran compiler 4 vs 11

I am porting an application from fortran older version (4.0) to new version (11.0). While porting I am facing some problems with real*4 variables:
real*4 a,b,c
a=0.9876875
b=0.6754345
c=a*b
value for c in old compiler 0.667118, which is correct value. But with new compiler I am getting a small variation from the output(c variable) like 0.667120. Though it is a small variation, I am using these values in some other calculation. So the overall output has a huge difference. How to overcome this issue?
You are, I'm assuming, going from Microsoft Fortran Powerstation 4 to Intel Visual Fortran 11.xx ?
Anyways, try this:
program test32
integer, parameter :: iwp = selected_real_kind(15,300)
real(iwp) :: a,b,c
a=0.9876875
b=0.6754345
c=a*b
write(*,'(3f12.8)')a,b,c
end program test32
which gives out:
0.98768753 0.67543453 0.66711826
I will not explain selected_real_kind, not because I do not wish, but because the help will probably do it much better. But, do ask if something in here is not clear.
p.s. The representation of real*4, or any type of real is processor dependent, and compiler dependent and that is one of the reasons why you're getting different results.
Discussion of changes in Intel visual Fortran compiler version 11 here:
http://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/68587/
The upshot is that older versions of the Fortran compiler would implicitly promote single-precision values to double-precision before performing an operation. The default behavior in version 11 is to perform the operation with single-precision. There are compiler options (/arch:ia32) to enable the old behavior in the new compiler.
I assume you are using Intel. Try to compile without optimization..

How to identify fortran standard - '77, '90, or '95?

I have a piece of fortran code, and I am not sure which standard it is - '77, '90 or '95. Is there a standard tool to identify which standard it subjects to?
There probably are automated tools, but my methods are largely heuristic:
Do comments use a ! anywhere on the line (F90+) or a C in the first column (F77)?
Do loops use do..end do (F90+) or do..continue (F77)?
Are lines continued using & at the end of the line (F90+) or in column 6 (f77)?
Does the code use module or type structures (F90)?
If the code uses arrays, does it operate on them as a single structure (F90) or always using loops (F77)?
Is dynamic memory (either using allocatable or pointer methods) used (F90)?
Generally these are enough to discriminate between F90 and F77. The differences between Fortran 90 and FORTRAN 77 are much, much larger than the differences between Fortran 90 and Fortran 95 so I usually stop there.
If you have access to GNU Fortran (gfortran) you can try compiling it with the different options for --std and see which one works. You can find details on the dialect options here.
I'm adding features in fortran 2003 and 2008 (which are just back of my head)
if the program has parameterized-derived datatypes (fortran 2003.)
if the array constructor uses square brackets [ ] instead of (/ /) (fortran 2003.)
if you see,there is provision of using coarrays (fortran 2008)
although many compilers have special functions(like Bessel functions) as part of extensions , it is a bonafide fortran 2008 feature.
(if any discrepancies let me know i'll edit)