Is common allowed in gfortran

I'm converting FORTRAN code from HP-UX FORTRAN over to gfortran on a RedHat Linux system.

I'm having problems with the COMMON statements not behaving the same way as programs coming from the HP system, on the Linux system using gfortran (4.4.?). Once I abandon common and pass the variables as arguments to the subroutines the program gives the correct results.

Does gfortran fully support use of COMMON? Is the behaviour different?
Is it somehow related to the correct or different or more strict use of the SAVE statement in conjunction with COMMON (something I know nothing about)?

p.s Why don't I see the FORTRAN category to post this in, something I did recently? (Admin please add this to FORTRAN if it can be done, it just no longer appears as an option in programming languages for me)

Any help much appreciated.

Cheers,
Max
madmax61Asked:
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

x
 
dcesariConnect With a Mentor Commented:
Well the file extension in gfortran (and most fortran compilers) determines the expected source format (i.e. fixed form or free form) not the fortran standard supported, which in gfortran is controlled by the -std= option (see man gfortran). Moreover, as far as I know, COMMON blocks are allowed in f95 and in f2003 as well, so the file format/extension should not be a problem.

But, of course, common block is really an old and uncomfortable feature which I have't used for years, so I have no experience of how it is suppoorted in gfortran. If you provide a simple example of failing code I could try to give more help. Another suggestion: try to compile with -Wall option (enable all warnings), maybe there is some nonstandard use of COMMON in your failing example/program.
0
 
cupCommented:
It depends on the file extension.  gfortran works on file extensions.  If it is .f or .for, then it assumes it is f77 so common is allowed.

If it is f90, common is allowed

If it is f95, common is not allowed (if you adhere to the standard)

Save variables are to do with presistence.  It assumes that values remain persistent on re-entry.
0
 
madmax61Author Commented:
I am using the .f90 extension, and it isn't working properly for me.
If it is not allowed in the f95 standard then I might head in the direction of trying to eliminate the common statements rather than attempting to make them work.
 
I might write a simple test program and see what that does. I'm porting over 80 or so programs, most of which are FORTRAN 77 and 90. Some use common. I'm sure I've successfully ported one that used common, yet 2 at least recently failed specifically in the common statement, not doing as I expected.  
 
Thanks for the reply.
Cheers,
Max
0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
madmax61Author Commented:
A simple test case of one integer variable in a common and setting it in both the main and subroutine, behaved as expected.
The failing code mentioned above had a dozen or so variables, possibly differing types, and rather large multimensional and single dimensional arrays of varying sizes, and not in order of largest to smallest as I've seen mentioned as advisable, in my searches.
0
 
cupCommented:
Is it possible that there is a typo in the variable names.  Try IMPLICIT NONE (A-Z) before the common block and see what comes out.
0
 
madmax61Author Commented:
Some code from the program I had to port ('implicit none' NOT used). The main problem was the mrain, krain arrays were updated in one or both subroutines but when referenced in main later the values were different to what was set. Variables were not likely typo'd as they were working in a previous life.

PROGRAM AAA

COMMON NAME(20),B(12,12),IX(750),IPER(10),LX(10),A(201),AX(24),LRAIN(201,12),JRAIN(1000),KRAIN(1000),MRAIN(201,10),LC(10),LR(10)
 
END PROGRAM AAA

 
SUBROUTINE BBB(LA,LB,K,NB,LIM,NOPAR)

COMMON NAME(20),B(12,12),IX(750),IPER(10),LX(10),A(201),AX(24),LRAIN(201,12),JRAIN(1000),KRAIN(1000),MRAIN(201,10),LC(10),LR(10)
 
variables used inside subroutine BBB: II, NOPAR, LA, LC(K), K, LR, I, MRAIN, LB, NB, LIM, KRAIN, J
 
 
LR, LC, MRAIN, KRAIN passed via common and used in subroutine(the rest not actually used in the subroutine)
 
 
SUBROUTINE CCC(LR,JCAL,ICAL,NOCUT)

COMMON NAME(20),B(12,12),IX(750),IPER(10),LX(10),A(201),AX(24),LRAIN(201,12),JRAIN(1000),KRAIN(1000),MRAIN(201,10),LC(10),LR(10)
 

 
LR(I), LC( ), MRAIN( ), IX passed via common (the rest not actually used in the subroutine)
 
 
p.s. Testing a small program does indeed show common works as I expect, but as you can see the above code is a more complex example, and which works on our HP system, but not in Linux gfortran44.
0
 
dcesariCommented:
I tested the attached code,derived from your example, with gfortran 4.4.4, even linking main program and subroutines from different source files, and the printed values look as expected, so it seems that the tested variables are really in common (the only thing I modified is the LR argument in CCC which has been renamed because it coincides with a variable in the common block).

So it seems I cannot reproduce your bug, can you comment on this? Maybe you were meaning a different problem?
PROGRAM AAA
COMMON NAME(20),B(12,12),IX(750),IPER(10),LX(10),A(201),AX(24),LRAIN(201,12),JRAIN(1000),KRAIN(1000),MRAIN(201,10),LC(10),LR(10)

LR(:) = -7
LC(:) = -9
MRAIN(:,:) = -11
KRAIN(:) = -13
IX(:) = -15
LX(:) = -17

CALL bbb()
CALL ccc()

END PROGRAM AAA


SUBROUTINE BBB(LA,LB,K,NB,LIM,NOPAR)
COMMON NAME(20),B(12,12),IX(750),IPER(10),LX(10),A(201),AX(24),LRAIN(201,12),JRAIN(1000),KRAIN(1000),MRAIN(201,10),LC(10),LR(10)

PRINT*,'BBB'
PRINT*,MAXVAL(lr),MINVAL(lr)
PRINT*,MAXVAL(lc),MINVAL(lc)
PRINT*,MAXVAL(mrain),MINVAL(mrain)
PRINT*,MAXVAL(krain),MINVAL(krain)
PRINT*,MAXVAL(ix),MINVAL(ix)
PRINT*,MAXVAL(lx),MINVAL(lx)

END SUBROUTINE BBB


!SUBROUTINE CCC(LR,JCAL,ICAL,NOCUT)
SUBROUTINE CCC(LS,JCAL,ICAL,NOCUT)

COMMON NAME(20),B(12,12),IX(750),IPER(10),LX(10),A(201),AX(24),LRAIN(201,12),JRAIN(1000),KRAIN(1000),MRAIN(201,10),LC(10),LR(10)

PRINT*,'CCC'
PRINT*,MAXVAL(lr),MINVAL(lr)
PRINT*,MAXVAL(lc),MINVAL(lc)
PRINT*,MAXVAL(mrain),MINVAL(mrain)
PRINT*,MAXVAL(krain),MINVAL(krain)
PRINT*,MAXVAL(ix),MINVAL(ix)
PRINT*,MAXVAL(lx),MINVAL(lx)

END SUBROUTINE CCC

Open in new window

0
 
madmax61Author Commented:
Thankyou all for your replies.
Thankyou for the testing dcesari.
I built up a test example and gradually made it more and more complex and on every occasion it behaved as expected, so in a test program I could not demonstrate the problem.
The program that was failing however showed there was a problem, as I did the same thing as you did dcesari by doing prints before during and after calls to subroutines which modified the common variables and the results were unexpected/wrong and caused different answers to similar code on the HP. By changing the variables to arguments in the subroutines and removing them from common the results were the same across the HP and Linux systems.
As I have a truckload of programs to port across in limited timeframe I don't think I will spend any more time on it, unless it starts biting my backside again later in this program porting exercise. I'll simply take common out of the equation to fix any problems that arise.
 
No idea who I should allocate points to, or just share it around for efforts involved. I shall ponder! (If I do revisit the offending code and discover anything I shall endeavor to post here.)
 
Many thanks.
Max
0
 
madmax61Author Commented:
p.s. I mistakenly added the LR in the 2nd subroutine, as I was beginning to test out passing the variable as an argument rather than via common at that stage and forgot to clean it out when posting, well picked up dcesari.
0
 
dcesariConnect With a Mentor Commented:
If you want to get rid of common, which is a good idea, the simplest thing to do is to put those variables in a (fortran 90) module, rather than passing them over to every subroutine, something like the attached code, then every subroutine/function that needs them may simply include the instruction "USE common_data" to gain access to those variables. The module solution works best if the module is in a separate source file.

If you need any kind consultancy in field of fortran programming, please contact me directly (see my profile).
MODULE common_data

INTEGER :: NAME(20), IX(750), IPER(10), LX(10), LRAIN(201,12), &
 JRAIN(1000), KRAIN(1000), MRAIN(201,10), LC(10), LR(10)

REAL :: B(12,12), A(201), AX(24)

END MODULE common_data

Open in new window

0
 
madmax61Author Commented:
Whilst I could not replicate the problem in a small section of code I found the answers to assist greatly.

Many thanks,
Max
0
All Courses

From novice to tech pro — start learning today.