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

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)

Related

Find an alternative for norm2() and move_alloc() in Fortran 95

I write code based on modern Fortran. For some reason, I want to modify it in a way that is compatible with the old version. Converting from the latest version to version 95 is desirable here. I have trouble with two intrinsic functions. "Mov_alloc" and "Norm2" are parts of these functions.
I want to know: are there any intrinsic functions for them in Fortran 95? Or, are there any external functions that do the same job precisely?
You can easily implement norm2() yourself based on the definition. Some care must be taken if your numbers are so large that overflow is an issue. But the simplest version is as simple
norm2 = sum(A**2)
There is no equivalent of move_alloc() in Fortran 95. You may need to use pointers instead of allocatable variables. You could implement your own version in C, but that would require many features from Fortran 2003-2018, so it makes little sense for you.
You can consider reallocating your arrays yourself and copying the data instead of doing move_alloc():
if (allocated(B)) deallocate(B)
allocate(B(lbound(A,1):ubound(A,1)))
B(:) = A
deallocate(A)
However, it is not the same as move_alloc().

Is there a setting or workaround in gFortran to the Microsoft Fortran 5.1 $STORAGE Metacommand

We have some (a huge libray or 40+ modules) old Fortran code than needs updating and compiling with a more recent compiler.
Is there anyway to set gFortran to allow for the $STORAGE:2 metacommand as used by old MS Fortran 5.1?
According to: https://support.microsoft.com/en-us/kb/51471
The $STORAGE:n metacommand allocates "n" bytes of memory for all INTEGER and LOGICAL variables. For example, when an application specifies the $STORAGE:2 metacommand and declares an INTEGER variable B, the compiler allocates two bytes for B instead of four. The $STORAGE metacommand does not affect memory allocation when a declaration includes an explicit length specification, such as an INTEGER*2 or INTEGER*4.
I wish it was a simple matter of rewriting the variable declarations to use integer*2. However the programmer who wrote it, uses tons of implicit variable declarations and many EQUIVALENCE statements everywhere that are troublesome to deal with:
$STORAGE:2
CHARACTER*2 ABC
EQUIVALENCE (ABC,ITT)
There is no way I know in modern compilers to do this for 16 bit integers.
Compilers usually allow promoting integer kinds by a command line switch, but I don't recall any modern free compiler to allow a change to 16 bit ones.
I would suggest rewriting the variable declarations to use integer*2 instead instead of the directive.

Allocatable arrays in fortran 77 and gfortran

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.

Query integrating Fortran and C++ code

I'm trying to integrate some C++ code into Fortran.
I have a doubt with equivalences between types,
is Fortran integer*1 equivalent to C++ bool?¿ if not, what is the correct C++ equivalent type?¿
Thank you so much in advance!
quoting from this link:
The INTEGER(1) type should be used for large arrays when memory is at
a premium for variables which will have only positive, negative, and
zero whole number values within the range of -129 to 127..
So, I'd say its C/C++ equivalent would be a signed char. The equivalent of bool is Fortran's logical type.
EDIT: M.S.B.'s answer is way better than mine; you're way better off doing what (s)he suggested.
The best thing to do is to use the Fortran ISO_C_Binding which provides types that match C types. That approach is compiler and platform independent. I'm less sure about C++ types but if you are sure of their C equivalent you should be good. The ISO_C_Binding provides the Fortran type C_BOOL to match the C type _Bool. The binding provides a long list of equivalent types. One place that the list appears is in the chapter "Intrinsic Modules" of the gfortran manual. Also see the "Mixed Language Programming" chapter. While I have cited the gfortran manual, as part of the Fortran 2003 language standard these features aren't particular to that compiler.
P.S. A comment suggests the use of int8_t. The matching type, on the Fortran side with the ISO C Binding, is C_INT8_T.

Fatal error F1002 compiler is out of heap space in pass 2 in MS Fortran Powerstation

I have a FORTRAN 77 program code. I am using Fortran Power Station 4.0 on Windows. It is a very long Finite element method code.
The code is the following :
1 Main Program starts with
PARAMETER (HLENGTH=600.0,VLENGTH=600.0,NHELE=6,NVELE=6,NTYPE=1)
PARAMETER (DENSITY=2.78E-6,POISON=0.34,THICK=1.0,EMODULE=6.87E4)
PARAMETER (NTOTALNODE=(NHELE+1)*(NVELE+1))
PARAMETER (NHNODE=NHELE+1,NVNODE=NVELE+1)
PARAMETER (MK=(NTOTALNODE-2*NHNODE-2*(NVNODE-2))*5)
PARAMETER (DELTAH=(HLENGTH+0.0)/(NHELE+0.0))
PARAMETER (DELTAV=(VLENGTH+0.0)/(NVELE+0.0))
DIMENSION NODEMATRIX(NTOTALELE,4)
REAL*8 STIFFMATRIX(20,20),MASSMATRIX(20,20)
REAL*8 STIFFMATRIXS(20,20),MASSMATRIXS(20,20)
DIMENSION NODEROWT(4),NODEROWT2(20)
DIMENSION NM(NVNODE,NHNODE)
REAL*8 GSM(NTOTALNODE*5,NTOTALNODE*5),NCARRIER(MK),
&GMM(NTOTALNODE*5,NTOTALNODE*5),AA(MK,MK),BB(MK,MK)
CALL STIFFMAT(STIFFMATRIX,DELTAV,DELTAH,THICK,EMODULE)
CALL MASSMAT(MASSMATRIX,DELTAV,DELTAH,THICK,DENSITY)
CALL STIFFMATS(STIFFMATRIXS,DELTAV,DELTAH)
CALL MASSMATS(MASSMATRIXS,DELTAV,DELTAH,DENSITY)
.
.
.
. etc
2 - The Subroutins are starts as following:
SUBROUTINE STIFFMAT(STIFFMATRIX,DELTAV,DELTAH,THICK,EMODULE)
REAL*8 STIFFMATRIX(20,20),B(6,20),BT(20,6),D(6,6)
REAL*8 CC(5),ZETAM(5),ETAM(5),CA,CB,ZETA,ETA,SUM,SUM2,SUM3
.
.
.etc
SUBROUTINE MASSMAT(MASSMATRIX,DELTAV,DELTAH,THICK,DENSITY)
REAL*8 MASSMATRIX(20,20),B(5,20),BT(20,5),D(5,5)
REAL*8 CC(5),ZETAM(5),ETAM(5),CA,CB,ZETA,ETA,SUM,SUM2,SUM3
.
.
.etc
SUBROUTINE MASSMATS(MASSMATRIXS,DELTAV,DELTAH,DENSITY)
REAL*8 MASSMATRIXS(20,20),B(5,20),BT(20,5),D(5,5),IS,JS,AS
REAL*8 CC(5),ZETAM(5),CA,ZETA,ETA,SUM,SUM2,SUM3
.
.
.etc
SUBROUTINE STIFFMATS(STIFFMATRIXS,DELTAV,DELTAH)
REAL*8 STIFFMATRIXS(20,20),B(3,20),BT(20,3),D(3,3)
REAL*8 CC(5),ZETAM(5),CA,ZETA,ETA,SUM,SUM2,SUM3
.
.
.etc
When I press the compile command it shows me the following message :
fatal error F1002: compiler is out of heap space in pass 2
I Googled the problem, and found the following solutions
But I did not understand the solution!
I do not know how to change the Zi option, where I can find it?
I think my code is good and clear. Does any one have any suggestions to solve this problem?
If the project workspace is placed in nested folders resulting in large path, then powerstation compiler shows this error. The solution for this, is to reduce the path of the project workspace by placing it closer to c drive , for example in my documents folder.
There is only so much help that can be given over the internet. And only so much that can be done with an outdated product (MS Fortran Power Station) for which you lack the documentation. I have several suggestions. Get a modern compiler. With your computer experience, and since you are using MS Windows, you would probably do best with a commercial product such as Intel Visual Fortran Compiler for Windows.
There may be an educational discount. There is probably a trial download (timed demo). If you still have difficulties (installing, compiling your program, etc.), offer some money to a undergraduate who is good with computers to help you for a couple of hours. I also suggest learning Fortran 95. You can gradually switch from FORTRAN 77 to Fortran 95 since the languages are compatible. Fortran 95 is a more capable language. It also has features that better allow compilers to find programmer mistakes, speeding the development process.
From the link you provided:
There are three different ways to resolve these problems:
Reorder the structure. Putting small
items first often eliminates both
errors. -or-
Use one-character-long member names.
-or-
Recompile without -Zi.
If you're compiling with the -Zi parameter, take the parameter off.
If that doesn't work, reorder the structure. That means putting the smaller individual INTEGER, FLOAT, etc. elements towards the front of the program, followed by the Array declarations.
If that doesn't work, your program is too large for Fortran power station.
I have a similar problem when I make the "Project Workspace" name too long. Use short "Project Workspace" name.