Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Program Fails When Parameter Fixed Constants are Changed (F77) ??

17 views
Skip to first unread message

monir

unread,
Apr 1, 2009, 11:59:38 AM4/1/09
to
Hello;

Please have a look at the following and kindly advise on what I did
wrong!

1) The program works fine with:
in common DIM: nRdim=8, nTHdim=10, nPlanes=10
in DCpZeros: PARAMETER (maxPln=10, maxR=8, maxTH=10, tol=1.E-5)
in Polint: Parameter (nmax=20)
in Polin2: Parameter (nmax=20, mmax=20)

2) Program fails with:
in common DIM: nRdim=10, nTHdim=30, nPlanes=10
in DCpZeros: PARAMETER (maxPln=10, maxR=15, maxTH=30, tol=1.E-5)
in Polint: Parameter (nmax=30)
in Polin2: Parameter (nmax=30, mmax=30)

3) The input array VxGrid(j,k) is correctly printed just before Call
Polin2(). It DOES NOT suppose to change after the call, but it
mysteriously does, most likely due to incorrect declarations!!

4) The relevant code (F77) is provided below. It compiles correctly
with g95.

Your help and advice would be greatly appreciated.
Monir

C
****************************************************************
SUBROUTINE DCpZeros
C
****************************************************************
C This subroutine determines the abscissas of a potential minimum of
Cp
C on a given R-TH (T*=const) planes.
C
PARAMETER (maxPln=10, maxR=15, maxTH=30, tol=1.E-5)
...................................
Dimension xbys(maxPln,maxR,maxTH), rbys(maxPln,maxR,maxTH)
Dimension theta(maxPln,maxR,maxTH)
Dimension vxbyu(maxPln,maxR,maxTH), vrbyu(maxPln,maxR,maxTH)
Dimension vthbyu(maxPln,maxR,maxTH)
Dimension Rgrid(maxR), Tgrid(maxTH)
Dimension VxGrid(maxR,maxTH)
..................................
COMMON /DIM/ nRdim,nTHdim,nPlanes !currently 10, 30, 10
COMMON /ABSCISAE/ xbys,rbys,theta
COMMON /VvALUES/ vxbyu, vrbyu, vthbyu

! .......my code1.................
DO 99 I=1,nPlanes
DO 90 J=1, nRdim
DO 90 K=1, nTHdim
Rgrid (J) = rbys (I,J,K)
Tgrid (K) = theta(I,J,K)
VxGrid(J,K) = vxbyu(I,J,K)
c the entire Rgrid, Tgrid , VxGrid arrays are printed correctly
90 Continue

Call Polin2
(Rgrid,Tgrid,VxGrid,nRdim,nTHdim,Rp,THp,VxCentre,accx)

! arrays Rgrid & Tgrid remain undistorted and printed correctly
! input array VxGrid array is now distorted, and both VxCentre and
accx return NaN!!!

99 Continue
! my code2.................
Return
End

C ****************************************************************
SUBROUTINE Polin2 (x1a, x2a, ya, m, n, x1, x2, y, dy)
C ****************************************************************
C [ N.R., p 97 ] reliable 2D interpolation routine

PARAMETER (nmax=30, mmax=30)
Dimension x1a(m), x2a(n), ya(m,n), yntmp(nmax), ymtmp(mmax)

do 12 j=1, m
do 11 k=1, n
yntmp(k) = ya(j,k)
c ya array doesn't print correctly here !! why ??
11 continue
call polint (x2a, yntmp, n, x2, ymtmp(j), dy)
12 continue
call polint (x1a, ymtmp, m, x1, y, dy)
Return
End

C
****************************************************************
SUBROUTINE Polint (xa, ya, n, x, y, dy)
C
****************************************************************
C N.R., p 82. reliable 1D interpolation routine

PARAMETER (nmax=30)
Dimension xa(n), ya(n), c(nmax), d(nmax)

ns = 1
dif = ABS(x - xa(1))
DO 11 i=1,n
dift = ABS(x-xa(i))
IF (dift .LT. dif) Then
ns = i
dif = dift
EndIF
c(i) = ya(i)
d(i) = ya(i)
11 CONTINUE
y = ya(ns)
ns = ns - 1
DO 13 m=1,n-1
DO 12 i=1,n-m
ho = xa(i) - x
hp = xa(i+m) - x
w = c(i+1) - d(i)
den = ho - hp
IF(den .EQ. 0.) PAUSE 'Two XAs values are identical'
den = w/den
d(i) = hp*den
c(i) = ho*den
12 Continue
IF(2*ns .LT. n-m) Then
dy = c(ns+1)
Else
dy = d(ns)
ns = ns - 1
EndIF
y = y+dy
13 Continue
Return
End

dpb

unread,
Apr 1, 2009, 12:53:49 PM4/1/09
to
monir wrote:
...

> Please have a look at the following and kindly advise on what I did
> wrong!
...

> 3) The input array VxGrid(j,k) is correctly printed just before Call
> Polin2(). It DOES NOT suppose to change after the call, but it
> mysteriously does, most likely due to incorrect declarations!!
>
> 4) The relevant code (F77) is provided below. It compiles correctly
> with g95.
>
> Your help and advice would be greatly appreciated.
...

I would guess what you did wrong was to compile/run w/o bounds checking
turned on.

Secondly, assuming "compiles correctly" doesn't imply no logic or
addressing errors.

Almost certainly you have a bounds error and bounds checking will point
out where.

--

monir

unread,
Apr 1, 2009, 4:47:40 PM4/1/09
to

Hi dpb;

1) I compiled the program with the command:
>g95 -fbounds-check -o PRSCAV8d PRSCAV8d.for
No error messages of any sort!

2) Let me correct myself and add couple of clarifications for the
reader:
a. sub Polin2 returns to DcpZeros the value of VxCentre and accx
b. sub Polint returns to Polin2 the value of y and dy
c. 2D array VxGrid is local
d. 2D array ya is NOT shared between sub Polin2 and its subsidary sub
Polint

3) The array VxGrid(j,k) checks correctly before and after Call Polin2
(). It's the corresponding array argument ya in sub Polin2 that's
causing the troubles (for whatever reason) and I couldn't figure out
why!

4) For example: the first 7 values printed before and after Call Polin2
() are:
J.....k.....VxGrid
1.....1....-1.72088
1.....2....-1.74088
1.....3....-1.71389
1.....4....-1.68220
1.....5....-1.63843
1.....6....-1.52468
1.....7....-1.36799

and the corresponding values of ya (printed within loop 11, sub
Polin2) are:
J.....k......ya
1.....1....-1.72088 { = VxGrid(1,1)}
1.....2.....0.12347 (??)
1.....3.....0.42257 (??)
1.....4....-1.71389 { = VxGrid(1,3)}
1.....5....-0.04283 (??)
1.....6....-1.28948 (??)
1.....7....-1.63843 { = VxGrid(1,5)}
......8............ (??)
......9............ (??)
1....10....-1.36799 { = VxGrid(1,7)}

Not conforming correctly to the elements of the input array VxGrid
causes Polin2 to return NaN.

Will keep trying! Please let me know if you've any suggestions.

Regards.
Monir

mecej4

unread,
Apr 1, 2009, 5:17:30 PM4/1/09
to
monir wrote:

That only shows that there were no violations were found at compile time. You should run the compiled program to detect run-time violations
>
<--CUT-->

--
-- mecej4

Louis Krupp

unread,
Apr 1, 2009, 5:20:04 PM4/1/09
to

As a general rule, if you remove everything except the parts that are
giving you trouble, it's easier to see what's wrong. It's hard to read
a lot of code looking for the important stuff.

In this case, it *looks* like VxGrid is dimensioned (15, 30) and is
passed to Polin2 which thinks the array (which it knows as ya) is
dimensioned (10, 30). This is a problem; ya(1, 2) is not in the same
place as VxGrid(1, 2).

One way to solve this is to pass the true dimensions of VxGrid as
arguments to Polin2 and dimension ya accordingly.

Louis

ken.fa...@gmail.com

unread,
Apr 1, 2009, 5:42:05 PM4/1/09
to
On Apr 1, 1:47 pm, monir <mon...@mondenet.com> wrote:
[...]

> 3) The array VxGrid(j,k) checks correctly before and after Call Polin2
> ().  It's the corresponding array argument ya in sub Polin2 that's
> causing the troubles (for whatever reason) and I couldn't figure out
> why!
>
> 4) For example: the first 7 values printed before and after Call Polin2
> () are:
> J.....k.....VxGrid
> 1.....1....-1.72088
> 1.....2....-1.74088
> 1.....3....-1.71389
> 1.....4....-1.68220
> 1.....5....-1.63843
> 1.....6....-1.52468
> 1.....7....-1.36799

Louis Krupp has the correct diagnosis, but I think
it needs to be stated that the above list is *not*
the first 7 locations of VxGrid. In Fortran, arrays
are arranged so that varying the 1st index, J in
this case, are the elements closest together.

There for VxGrid(1,1) is followed by VxGrid(2,1).
However VxGrid(1,1) has 14 elements between it
and VxGrid(1,2) given:

PARAMETER (maxPln=10, maxR=15, maxTH=30, tol=1.E-5)

and

Dimension VxGrid(maxR,maxTH)

i.e., VxGrid(15,30).

> and the corresponding values of ya (printed within loop 11, sub
> Polin2) are:
> J.....k......ya
> 1.....1....-1.72088 { = VxGrid(1,1)}
> 1.....2.....0.12347 (??)
> 1.....3.....0.42257 (??)
> 1.....4....-1.71389 { = VxGrid(1,3)}
> 1.....5....-0.04283 (??)
> 1.....6....-1.28948 (??)
> 1.....7....-1.63843 { = VxGrid(1,5)}
> ......8............ (??)
> ......9............ (??)
> 1....10....-1.36799 { = VxGrid(1,7)}

In the call to Polin2, you don't use maxR
and maxTH, instead you use the common
variables nRdim and nTHdim which are set
to 10 and 30. So within Polin2,
ya(1,1) had only 9 elements between it and
ya(1,2), not the 14 elements between
VxGrid(1,1) and VxGrid(1,2). That's the
technical problem.

The conceptual problem is that in Fortran,
if you want an "adjustable" array (for lack
of a better term), the dimension that varies
must be the last. Invert your use of the
indexes J and K and you should be OK. In
this particular case...

Better would be to review an introductory
Fortran text to get some basic understanding
of the language's array layout, etc.

-Ken

monir

unread,
Apr 1, 2009, 9:55:25 PM4/1/09
to
On Apr 1, 5:42 pm, ken.fairfi...@gmail.com wrote:
> On Apr 1, 1:47 pm, monir <mon...@mondenet.com> wrote:

mecej4;

>"That only shows that there were no violations were found at compile time. You should run the compiled program to detect run-time violations"

1) The limited tabulated results in my OP were from running the
compiled program.

==============================================

Louis;

>"In this case, it *looks* like VxGrid is dimensioned (15, 30) and is passed to Polin2 which thinks the array (which it knows as ya) is dimensioned (10, 30). This is a problem; ya(1, 2) is not in the same place as VxGrid(1, 2)."

2) Yes, this is a problem, but how to solve it appreciating that
Polin2 is a N.R. published reliable routine!

>"One way to solve this is to pass the true dimensions of VxGrid as arguments to Polin2 and dimension ya accordingly."

3) I believe that's exactly what I have! The true dimensions of
VxGrid (nRdim,nTHdim) are passed to Polin2 as arguments, and ya is
dimensioned accordingly as ya(m,n) in Polin2.
Have I misinterpreted your suggestion ??

============================================

Ken;

>"In the call to Polin2, you don't use maxR and maxTH, instead you use the common variables nRdim and nTHdim which are set to 10 and 30. So within Polin2, ya(1,1) had only 9 elements between it and ya(1,2), not the 14 elements between VxGrid(1,1) and VxGrid(1,2). That's the technical problem.

>"The conceptual problem is that in Fortran, if you want an "adjustable" array (for lack of a better term), the dimension that varies must be the last. Invert your use of the indexes J and K and you should be OK."

4) I've inverted the indices J and K in Polin2 as per your suggestion:
...............................
do 12 k=1, n ! =30
do 11 j=1, m ! =10
yntmp(k) = ya(j,k)


11 continue
call polint (x2a, yntmp, n, x2, ymtmp(j), dy)
12 continue

...............................

5) Now the values of ya (printed within loop 11 , sub Polin2) are:
J......k.......ya(j,k)
1.....1....-1.72088 { = VxGrid(1,1)}
2.....1....-2.03183 { = VxGrid(2,1)}
3.....1....-2.56520 { = VxGrid(3,1)}
4.....1....-0.33580 { = VxGrid(4,1)}
5.....1....-0.35788 { = VxGrid(5,1)}
6.....1....-0.21987 { = VxGrid(6,1)}
7.....1....-0.70149 { = VxGrid(7,1)}
8.....1.... ...........
9.....1.................
10...1....-0.11598 { = VxGrid(10,1)}

1.....2.....0.05168 (???)
2.....2.....6.0231E+36 (???)
3.....2....-0.09750 (???)
.....................................

There must be something else causing this annoying distortion!

Regards.
Monir

Louis Krupp

unread,
Apr 2, 2009, 5:52:44 AM4/2/09
to
monir wrote:

> Louis;
>
>> "In this case, it *looks* like VxGrid is dimensioned (15, 30) and is passed to Polin2 which thinks the array (which it knows as ya) is dimensioned (10, 30). This is a problem; ya(1, 2) is not in the same place as VxGrid(1, 2)."
> 2) Yes, this is a problem, but how to solve it appreciating that
> Polin2 is a N.R. published reliable routine!
>
>> "One way to solve this is to pass the true dimensions of VxGrid as arguments to Polin2 and dimension ya accordingly."
> 3) I believe that's exactly what I have! The true dimensions of
> VxGrid (nRdim,nTHdim) are passed to Polin2 as arguments, and ya is
> dimensioned accordingly as ya(m,n) in Polin2.
> Have I misinterpreted your suggestion ??

VxGrid is dimensioned (maxR, maxTH) -- i.e., (15, 30) -- and if Polin2
thinks it's dimensioned (10, 30), you're going to get surprising
results. Remember, when you call Polin2, ya is *not* a copy of a part
of VxGrid; it's an array that starts at the same memory location as
VxGrid. ya(1, 1) is the same as VxGrid(1, 1) no matter how you
dimension ya, but if you expect ya(1, 2) to be the same as VxGrid(1, 2),
then the first dimension of ya had better be the same as the first
dimension of VxGrid.

If VxGrid is dimensioned (15, 30), then VxGrid(1, 2) is 15 elements past
VxGrid(1, 1). If ya is dimensioned (10, 30), then ya(1, 2) is ten
elements past ya(1, 1), which is the same as VxGrid(11, 1), and that's
probably not what you wanted.

I hope this makes sense.

To solve this problem, you might be able to dimension VxGrid (nRdim,
nTHdim) as long as nRdim and nTHdim are computed before entering DCpZeros.

I'm sure someone will correct me if I have any of this wrong.

If you find out what it is, you'll let us all know, right? :)

Louis

monir

unread,
Apr 2, 2009, 1:11:52 PM4/2/09
to
On Apr 2, 5:52 am, Louis Krupp <lkrupp_nos...@pssw.com.invalid> wrote:
> monir wrote:

Louis;

Your explanation makes a great sense, and thank you again for your
time!

1) "To solve this problem, you might be able to dimension VxGrid


(nRdim, nTHdim) as long as nRdim and nTHdim are computed before
entering DCpZeros."

Yes, nRdim and nTHdim are computed before entering sub DCpZeros, but
they're in a Common block. (plse see Item 4 below)

2) It appears that a sure (and possibly a safe) way is to set the
constants maxPln, maxR, maxTH of the Parameter statements to the
actual numerical values computed and shared in:
...Common /DIM/ nRdim,nTHdim,nPlanes !currently 10, 30, 10
That's to say, in sub DCpZeros:
...PARAMETER (maxPln=10, maxR=10, maxTH=30, tol=1.E-5)
This is the ONLY way (so far) I can get the program working properly!

3) I don't think one can substitute the numerical values in the
Parameter statement by the variable names of the Common block list.
Even if there's a way to do so, it would defeat the purpose of having
the Parameter statement in the first place (setting the anticipated
largest (fixed) values for constants in the program).

4) For now, if one dispenses with the Parameter statement altogether,
is there a way to use the integer variables names of the Common block
list in the array declarations ?? (your suggestion Item 1 above)
Probably not, unless perhaps if one coverts the code to F90 or F95 and
tries Dynamic Arrays. I've never used this feature and it would be a
bit risky, but at least I would have the current successful run to
compare with!

5) Suppose you experts look at a F77 code with:
PARAMETER (maxPln=10, maxR=10, maxTH=30, tol=1.E-5)
...................................
Dimension xbys(maxPln,maxR,maxTH), rbys(maxPln,maxR,maxTH)


Dimension Rgrid(maxR), Tgrid(maxTH)
Dimension VxGrid(maxR,maxTH)
..................................
COMMON /DIM/ nRdim,nTHdim,nPlanes !currently 10, 30, 10

..................................
and appreciate (based on 2 above) that the program appears to be only
working properly if:
maxR = nRdim
maxTH = nTHdim
maxPln = nPlanes

Now you want to either:
a) set the max anticipated values of maxR, maxTH, maxPln for the
program; or
b) ensure that:
- maxR is set "automatically" to nRdim
- maxTH is set "automatically" to nTHdim
- maxPln is set "automatically" to nPlanes
(automatically for lack of a better word, rather than manually setting
the numerical values in the Parameter statement and recompiling the
program each time any of the variables in the Common /DIM/ is or has
changed.

Regards.
Monir

Ron Shepard

unread,
Apr 2, 2009, 3:07:01 PM4/2/09
to
In article
<9cb9e6b7-e08e-4e24...@l13g2000vba.googlegroups.com>,
monir <mon...@mondenet.com> wrote:

> Now you want to either:
> a) set the max anticipated values of maxR, maxTH, maxPln for the
> program; or
> b) ensure that:
> - maxR is set "automatically" to nRdim
> - maxTH is set "automatically" to nTHdim
> - maxPln is set "automatically" to nPlanes
> (automatically for lack of a better word, rather than manually setting
> the numerical values in the Parameter statement and recompiling the
> program each time any of the variables in the Common /DIM/ is or has
> changed.

The easiest way to make sure all of your dimensions match up is to
allocate the array at the beginning of the program to the correct size,
put your subroutines in a module (so they will get an explicit
interface), and declare all of the dummy arrays as assumed shape.

real :: dummy(:,:,:)

This way, the language takes care of everything that you are currently
struggling with getting to match up. It is all done automatically.
That is one of the advantages of f90 and later compared to f77. You are
in a hole trying to get variables to match up with parameters, dummy
arguments to match actual arguments, getting common blocks to work, and
being confused about storage association and column major vs. row major
array storage. You don't really need to understand all that to get a
simple program to work.

There are other ways to do this, some with advantages and disadvantages
compared to the above, but at your point you need something simple that
works.

$.02 -Ron Shepard

Louis Krupp

unread,
Apr 2, 2009, 3:17:23 PM4/2/09
to

I don't really know if you can use common block variables to dimension a
local array or not. I don't have easy access to a Fortran compiler or a
copy of a Fortran manual. You could try it and see if it works with
your compiler. If you're trying to write portable code, then you're
correct to be wary of doing that, since I believe it's not in the
Fortran 77 standard.

As an alternative, you could declare VxGrid dimensioned (maxR, maxTH) in
another subroutine and then call DCpZeros passing VxGrid, nRdim, and
nTHdim. Then DCpZeros can dimension VxGrid (nRdim, nTHdim). As long as
the only code that touches VxGrid sees it dimensioned (nRdim, nTHdim),
you should be OK.

You're probably doing this already, but when you compute nRdim and
nTHdim, you should make sure that they are less than or equal to maxR
and maxTH, respectively. I see array bounds exceeded all the time, and
in C, where it's not as easy to catch the error.

Louis

glen herrmannsfeldt

unread,
Apr 2, 2009, 6:31:56 PM4/2/09
to
Louis Krupp <lkrupp...@pssw.com.invalid> wrote:
(big snip)


> I don't really know if you can use common block variables to dimension a
> local array or not. I don't have easy access to a Fortran compiler or a
> copy of a Fortran manual. You could try it and see if it works with
> your compiler. If you're trying to write portable code, then you're
> correct to be wary of doing that, since I believe it's not in the
> Fortran 77 standard.

I believe it is allowed in Fortran 66, it doesn't seem that
it would have been removed in Fortran 77.

-- glen

Richard Maine

unread,
Apr 2, 2009, 7:07:28 PM4/2/09
to
glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

It is allowed only if you play pedantic games and claim that a dummy
argument is a local array. (well, it is, sort of, but that's not the
real question).

Of course, it isn't allowed. You should know that. Remember the drill?
Fortran before f90 has *NO* dynamic allocation. Using a common variable
for a non-dummy array dimension would by dynamic.

(Doing your own suballocation of space within a static array isn't
dynamic allocation at the language/system level; the host array is still
static. And tricks with overindexing common are not and have never been
standard conforming.)

F90 is another matter. Yes, it is allowed there.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain

monir

unread,
Apr 4, 2009, 12:26:13 AM4/4/09
to
On Apr 2, 7:07 pm, nos...@see.signature (Richard Maine) wrote:
> glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
> > Louis Krupp <lkrupp_nos...@pssw.com.invalid> wrote:

Hello;

Thank you all for your helpful replies.

1) Ron Shepard's suggestion is a good one:


"The easiest way to make sure all of your dimensions match up is to
allocate the array at the beginning of the program to the correct
size, put your subroutines in a module (so they will get an explicit
interface), and declare all of the dummy arrays as assumed shape.
real :: dummy(:,:,:) "

Unfortunately, I know very little about F95 modules, dynamic arrays,
arrays operations, etc.

2) Louis Krupp's suggestion (which sounds the easiest to implement!) :
"You could declare VxGrid dimensioned (maxR, maxTH) in another


subroutine and then call DCpZeros passing VxGrid, nRdim, and nTHdim.
Then DCpZeros can dimension VxGrid (nRdim, nTHdim). As long as the
only code that touches VxGrid sees it dimensioned (nRdim, nTHdim), you
should be OK."

I have given it a try, and here's what I did.
(PS. I'm not concerned or worried about the array bounds exceeded!
There're sufficient built-in red flags in the program.)

3) First, with F77 code and g95 compiler, one definitely cannot use
common block variables to dimension a local array as some of you have
already advised.
Compilation Error:
"Variables '.....' cannot appear in a specification expression in a
PROGRAM"
Richard Maine and glen herrmannsfeldt correctly predicted that in
their replis.

4) Basically, forget about the maximum anticipated values maxR, maxTH
and maxPln. Dimension the arrays based on the computed nRdim, nTdim
and nPlanes, by including them as arguments in the call to the various
routines. Hence, don't need the Common block /DIM/ (which wouldn't
have worked anyway based on Item 3 above).

5) Algorithmically, the entire "earlier" program is treated now as a
subroutine called by a "new" main program.
(It's quite confusing trying to describe the changes. They will
become pretty obvious as you'll see. Here's the latest relevant parts
of the code.)

C ****************************************************************
PROGRAM MainPRSCAV8
C ****************************************************************
!....myCode1.........
nT = !integer numerical value....
nR = !integer numerical value....
nP = !integer numerical value....
Call PRSCAV8e (nP, nR, nT)
End

C
****************************************************************
Subroutine PRSCAV8e (nPlanes, nRdim, nTdim)
C
****************************************************************
Dimension xbys (nPlanes,nRdim,nTdim), rbys(nPlanes,nRdim,nTdim) !
Compiler error
!...myCode2..................
Call DCpZeros (nRdim, nTdim, nPlanes)
!...myCode3..................
Return
End

C
****************************************************************
SUBROUTINE DCpZeros (nP,nR,nT)


C
****************************************************************
C This subroutine determines the abscissas of a potential minimum of
Cp

C on a given R-TH (T*=const) plane.
...................................
dimension Rgrid(nR), Tgrid(nT)
dimension VxGrid(nR,nT)
! ...myCode4.................
Call Polin2 (Rgrid,Tgrid,VxGrid,nR,nT,Rp,THp,VxCentre,accx)
! ...myCode5.................
Return
End

6) The following Compiler Error message is displayed (reference to the
1st arg in the 1st dim statement in sub PRSCAV8e):
"Error: Array bound at (nPlanes) must be constant"
What ?? It's a constant equals 10

I'm trying to fix this latest problem (or even make sense of it!) with
no luck!

Any suggestion ??

Thank you.
Monir

Louis Krupp

unread,
Apr 4, 2009, 12:48:03 AM4/4/09
to
monir wrote:
<snip>

>
> C ****************************************************************
> PROGRAM MainPRSCAV8
> C ****************************************************************
> !....myCode1.........
> nT = !integer numerical value....
> nR = !integer numerical value....
> nP = !integer numerical value....
> Call PRSCAV8e (nP, nR, nT)
> End
>
> C
> ****************************************************************
> Subroutine PRSCAV8e (nPlanes, nRdim, nTdim)
> C
> ****************************************************************
> Dimension xbys (nPlanes,nRdim,nTdim), rbys(nPlanes,nRdim,nTdim) !
<snip>

> "Error: Array bound at (nPlanes) must be constant"
> What ?? It's a constant equals 10
>
> I'm trying to fix this latest problem (or even make sense of it!) with
> no luck!
>
> Any suggestion ??
>

For nPlanes to be a constant in the Fortran sense, you'd have to
declared it a parameter and set it to 10 (or whatever). You wouldn't be
able to change it without recompiling. As the code is written, nPlanes
is a subroutine argument, and with your current compiler and current
compiler options, you can't use it to dimension an array.

You might have to try something closer to my previous suggestion:

PROGRAM MainPRSCAV8
integer nzmax
parameter (nzmax = 1000) ! something that should always be big enough
dimension z(nzmax)
integer nzcount
...
nzcount = ... ! count of elements needed for this run, must be <= 1000
...
call s(z, nzcount)
...
end

subroutine s1(z, nzcount)
dimension z(nzcount)
...
! put stuff in z
...
call s2(z, nzcount)
...
return
end

subroutine s2(z, nzcount)
dimension z(nzcount)
...
! do something with z
...
return
end

Louis Krupp

unread,
Apr 4, 2009, 1:06:37 AM4/4/09
to
Louis Krupp wrote:

> For nPlanes to be a constant in the Fortran sense, you'd have to
> declared it a parameter and set it to 10 (or whatever). You wouldn't be
> able to change it without recompiling. As the code is written, nPlanes
> is a subroutine argument, and with your current compiler and current
> compiler options, you can't use it to dimension an array.

Make that: You can't use it to dimension a local array. You can use it
to dimension an array that has been passed as an argument.

Louis

James Van Buskirk

unread,
Apr 4, 2009, 1:12:45 AM4/4/09
to
"monir" <mon...@mondenet.com> wrote in message
news:b061475d-090a-4612...@z15g2000yqm.googlegroups.com...

> 3) First, with F77 code and g95 compiler, one definitely cannot use
> common block variables to dimension a local array as some of you have
> already advised.
> Compilation Error:
> "Variables '.....' cannot appear in a specification expression in a
> PROGRAM"
> Richard Maine and glen herrmannsfeldt correctly predicted that in
> their replis.

Nope, and this is a subtle point. It's only in the main program that
you can't use common block variables to dimension local arrays. You
could read the common block variables in your main program and then
call a subroutine whose local arrays are dimensioned according to the
common block variables. The local arrays would retain their original
shapes even if the common block variables subsequently changed, except
that when the the subroutine returns the arrays and their shapes would
be wiped clean. All specification expressions in the main program
must be initialization expressions but this is not true for
subprograms.

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


glen herrmannsfeldt

unread,
Apr 4, 2009, 2:03:09 AM4/4/09
to
Richard Maine <nos...@see.signature> wrote:
> glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
>> Louis Krupp <lkrupp...@pssw.com.invalid> wrote:
>> (big snip)

>> > I don't really know if you can use common block
>> > variables to dimension a local array or not.

>> I believe it is allowed in Fortran 66, it doesn't seem that
>> it would have been removed in Fortran 77.

> It is allowed only if you play pedantic games and claim that a dummy
> argument is a local array. (well, it is, sort of, but that's not the
> real question).

> Of course, it isn't allowed. You should know that. Remember the drill?
> Fortran before f90 has *NO* dynamic allocation. Using a common variable
> for a non-dummy array dimension would by dynamic.

Oops. I thought it was talking about dummy arrays, but
yes that should not be called local arrays.

Adjustable dummy arrays are normally dimensioned with
other dummy variables, but COMMON variables are allowed.

-- glen

Richard Maine

unread,
Apr 4, 2009, 3:28:29 AM4/4/09
to
James Van Buskirk <not_...@comcast.net> wrote:

> "monir" <mon...@mondenet.com> wrote in message
> news:b061475d-090a-4612...@z15g2000yqm.googlegroups.com...
>
> > 3) First, with F77 code and g95 compiler, one definitely cannot use
> > common block variables to dimension a local array as some of you have
> > already advised.

...


> Nope, and this is a subtle point. It's only in the main program that
> you can't use common block variables to dimension local arrays. You
> could read the common block variables in your main program and then
> call a subroutine whose local arrays are dimensioned according to the
> common block variables.

Of course, it would then not be f77 code. I forget why the OP was making
a point about the code being f77 and whether a particular reason for
this was stated. If one is willing to ue f90 or later constructs, then
life becomes hugely simpler for this kind of thing (dynamic array
sizing). To the extent that I generally consider it a waste of time to
explain to people how to fake it in f77.

monir

unread,
Apr 4, 2009, 6:23:50 PM4/4/09
to

Hello;

I tried Louis Krupp's suggestion but had a different problem!
1) In main:
First, I thought I might get away with just computing the actual
dimensions of the array and pass them as arguments to the subroutine.
It didn't work.
Second, I thought I might have to declare ALL the array variables used
in the subroutine and pass them ALL in the call statement. Instead, I
opted for declaring to the maximum anticipated a SINGLE 3D array
variable, computed the actual array size, and pass the single variable
name together with actual size to the subroutine as arguments (hoping
the compiler would recognize that the array bounds apply to ALL array
variables declared in the subroutine).
It appears that the g95 compiler might just have done that!

2) Here's the latest:

**********************************************
Program MainPRSCAV8e
**********************************************
Parameter (maxPln=25, maxR=35, maxTH=45)
Integer maxPln, maxR, maxTH
Dimension dummy (maxPln,maxR,maxTH)
!...myCode1.........


nT = !integer numerical value....
nR = !integer numerical value....
nP = !integer numerical value....

Call PRSCAV8e (dummy, nP, nR, nT)
End

*************************************************
Subroutine PRSCAV8e (xbys, nPlns, nRdim, nTdim)
*************************************************
Dimension xbys (nPlns,nRdim,nTdim), rbys(nPlns,nRdim,nTdim)
Dimension theta (nPlns,nRdim,nTdim), ...
!...many more similar declarations............
.....................
COMMON /ABSCISAE/ xbys,rbys,theta !compiler error
COMMON /VVALUES/ vxbyu,vrbyu,vthbyu
.....................
!....myCode2.........
Return
End

3) The good news is that No Longer the earlier Compiler Error message
appears:
"Error: Array bound at (nPlns) must be constant"
with reference to 1st arg in the 1st dim statement in sub PRSCAV8e.

4) That was encouraging for less than a milli second which took to
display the new Compiler Error message:
"Error: COMMON attribute conflicts with DUMMY attribute in 'xbys' "
(I've just tried in main to declare to the max anticipated ALL the
array variables used in the sub and passed ALL the variable names
together with the computed dimensions nP, nR, nT to the sub via the
call statement. More errors!

5) I tried to substitute the common block by moving its variables list
to the called subsidiary routine argument list (though I know that
would make the program less efficient - slower!). It didn't solve the
problem either.

Regards.
Monir

monir

unread,
Apr 4, 2009, 6:36:17 PM4/4/09
to

James;

I've just retrieved your recent reply and after I posted my latest. My
apologies!

"Nope, and this is a subtle point. It's only in the main program that
you can't use common block variables to dimension local arrays. You
could read the common block variables in your main program and then
call a subroutine whose local arrays are dimensioned according to the
common block variables. The local arrays would retain their original
shapes even if the common block variables subsequently changed, except
that when the the subroutine returns the arrays and their shapes would
be wiped clean. All specification expressions in the main program
must be initialization expressions but this is not true for
subprograms."

1) If my interpretation of your point is correct, then it would be a
straight forward solution and there should no problem!
Just to make sure we're on the same page:
a. I've F77 Program which calls many subroutines, DcpZeros, ReadInp,
Polint, Polin2, etc.
b. Many variables in the main program and subroutines are 3D and 2D
arrays
c. the actual dimensions of the arrays, say, nP, nR and nT are
computed in sub ReadInp.
d. in order to dimension the local arrays throughout I had to use
Parameter statements in the main program and subprograms to set the
maximum anticipated array sizes, say, maxP, maxR, maxT.
e. the program compiles fine as long as : nP<=maxP, nR<=maxR, nT<=maxT
f. The program would ONLY work properly if and only if : maxP=nP,
maxR=nR, maxT=nT
g. To ensure that: set reasonable values of maxP, maxR, maxT in the
Parameter statements. Compile & run the program (realizing it wouldn't
run correctly). Take note of the values nP, nR, nT. Re-set the fixed
constants in the Parameter statements. Re-compile & re-run.

2) My latest inquiry is:
If I can somehow dimension ALL program arrays based on the integer
variables nP, nR, nT computed in sub ReadInp, then there'll be no need
for the Parameter statements, setting/re-setting max values, re-
compiling, re-running, etc.
The question is how (F77) ???
Does your statement at the top help with/cover the above inquiry ??

Thank you kindly.
Monir

Louis Krupp

unread,
Apr 4, 2009, 7:16:22 PM4/4/09
to

Ne mi fahmam.

I'm not sure what you're trying to do or how you're hoping (a dangerous
word to use around computers) the compiler will do what you want.

Here's what I can tell you:

You can't have a variable in COMMON and an argument at the same time.
This won't work:

subroutine s(a)
common /.../a

As far as I can tell, you have two choices:

1. Do what I suggested earlier. It might take a while to write the
code to pass all those arrays and their working dimensions, but at the
end of the day, it's faster than trying variations on the theme and
hoping that something will work.

2. Learn about Fortran 95 dynamic allocation and modules and so on.
This will pay off in the long run. Others here will be able to answer
most of your questions better than I.

If you have questions about your code, strip it down to a small example
of what fails and post it. We're nerds. We read code, not English prose.

Good luck.

Louis

Richard Maine

unread,
Apr 4, 2009, 9:33:50 PM4/4/09
to
monir <mon...@mondenet.com> wrote:

> The question is how (F77) ???
> Does your statement at the top help with/cover the above inquiry ??

No, because as I mentioned in my reply, James' comment isn't about f77.
I have never noticed you mentioning exactly why you insist on f77,
though perhaps I missed it. Fundamentally, f77 does *NOT* have dynamic
array sizing. The various hacks used to work around that are just too
complicated to be worth describing. There is no good reason for new
programs today to be using those hacks.

In f90, it is easy. In f77, the answer is just plain, no. The kind of
dynamic sizing you are looking for is one of the big differences between
f77 and f90. If you are trying to get dyamic sizing in f77, you are just
wasting your time. The work to do that has been done... and it is called
f90.

monir

unread,
Apr 6, 2009, 11:40:37 AM4/6/09
to
On Apr 4, 7:16 pm, Louis Krupp <lkrupp_nos...@pssw.com.invalid> wrote:
> monir wrote:
>
> As far as I can tell, you have two choices:
>
> 1.  Do what I suggested earlier.  It might take a while to write the
> code to pass all those arrays and their working dimensions, but at the
> end of the day, it's faster than trying variations on the theme and
> hoping that something will work.
>
> 2.  Learn about Fortran 95 dynamic allocation and modules and so on.
> This will pay off in the long run.  Others here will be able to answer
> most of your questions better than I.
>
> If you have questions about your code, strip it down to a small example
> of what fails and post it.  We're nerds.  We read code, not English prose.
>
> Good luck.
>
> Louis- Hide quoted text -
>
> - Show quoted text -

Louis;

1) Richard Maine clearly and convincingly advised: "If you are trying
to get dynamic sizing in f77, you are just wasting your time."
He appears to have a very valid point!!

2) As per your suggestion, here's a non-working example.
It produces the compiler error:
"Error: ARRAY BOUND at (nPlns) MUST BE CONSTANT"
with reference to 1st arg *nPlns* in the 3rd dim statement in sub
PRSCAV8f:
... Dimension xbys1(nPlns,nRdim,nTHdim), rbys1(nPlns,nRdim,nTHdim).

PROGRAM MainPRSCAV8f


Parameter (maxPln=25, maxR=35, maxTH=45)
Integer maxPln, maxR, maxTH

Integer nP, nR, nTH
!--------------


Dimension xbys(maxPln,maxR,maxTH), rbys(maxPln,maxR,maxTH)
Dimension theta(maxPln,maxR,maxTH)

!--------------
nP = ... calculated integer numerical constant
nR = ... calculated integer numerical constant
nTH = ...calculated integer numerical constant
Call PRSCAV8f (xbys,rbys,theta, nP, nR, nTH)
End

C ***********************************************************
Subroutine PRSCAV8f (xbys,rbys,theta, nPlns,nRdim,nTHdim)
C ***********************************************************
Integer nPlns,nRdim,nTHdim

Dimension xbys(nPlns,nRdim,nTHdim), rbys(nPlns,nRdim,nTHdim)
Dimension theta(nPlns,nRdim,nTHdim)
!----------need to declare different arrays with the same size
Dimension xbys1(nPlns,nRdim,nTHdim), rbys1(nPlns,nRdim,nTHdim) !
problem
Dimension theta1(nPlns,nRdim,nTHdim)
!--------------
COMMON /ABSCISAE/xbys1,rbys1,theta1
!--------------
nPdum = nPlans
nRdum = nRdim
nTdum = nTHdim
!--------------
CALL ReadInp (nPdum, nRdum, nTdum)
CALL VelDeriv (nPdum, nRdum, nTdum)
!--------------
Return
End

Please modify the above as you see fit and let me try it one more
time.

Thank you kindly for your help.
Monir

dpb

unread,
Apr 6, 2009, 1:00:06 PM4/6/09
to
monir wrote:
...

> C ***********************************************************
> Subroutine PRSCAV8f (xbys,rbys,theta, nPlns,nRdim,nTHdim)
> C ***********************************************************
> Integer nPlns,nRdim,nTHdim
...

> !----------need to declare different arrays with the same size
> Dimension xbys1(nPlns,nRdim,nTHdim), rbys1(nPlns,nRdim,nTHdim) !
...

> Please modify the above as you see fit and let me try it one more
> time.

You've been given the reason that won't work in F77 and several choices
of what to do to fix it. Choose one. I recommend F90+ ALLOCATABLE.

Plonk... :(

--

Ron Shepard

unread,
Apr 6, 2009, 1:05:18 PM4/6/09
to
In article
<76539961-7039-4fca...@q9g2000yqc.googlegroups.com>,
monir <mon...@mondenet.com> wrote:

> 2) As per your suggestion, here's a non-working example.
> It produces the compiler error:
> "Error: ARRAY BOUND at (nPlns) MUST BE CONSTANT"
> with reference to 1st arg *nPlns* in the 3rd dim statement in sub
> PRSCAV8f:
> ... Dimension xbys1(nPlns,nRdim,nTHdim), rbys1(nPlns,nRdim,nTHdim).

These arrays are in a common block, but they are not referenced
after they are declared. So even if this were not a compiler error,
your declaration would do nothing useful.

As I said before, you are making this much, much, more complicated
than it needs to be. If I were writing a code like this, here is
one way I might do it with f90.


PROGRAM MainPRSCAV8f
use work_routines
...
nP = ... ! compute the dimensions here
nR = ...
nTH = ...
Call PRSCAV8f
contains
Subroutine PRSCAV8f
implicit none
real :: xbys(nP,nR,nTH), rbys(nP,nR,nTH)
real :: theta(nP,nR,nTH)

CALL ReadInp (xbys, rbys, theta,...)
CALL VelDeriv(xbys, rbys, theta,...)
Return
End subroutine PRSCAV8f
end program MainPRSCAV8f

module work_routines
contains
subroutine readinp( xbys, rbys, theta,...)
implicit none
real, intent(inout) :: xbys(:,:,:), rbys(:,:,:), theta(:,:,:)
...
end subroutine readinp
subroutine velderiv( xbys, rbys, theta,...)
implicit none
real, intent(inout) :: xbys(:,:,:), rbys(:,:,:), theta(:,:,:)
...
end subroutine velderiv
end module work_routines

There are other ways to do this, of course, but the important thing
is that this simplification avoids all of the problems you are
struggling with regarding common blocks, argument matching, and
maximum dimensions.

This assumes that you really do want to pass the arrays through the
argument list. You might not even need to do that. If all of your
work routines use the same three arrays, then you could make your
main program even simpler using an object-oriented approach like
this:

PROGRAM MainPRSCAV8f
use work_routines
implicit none
...
nP = ... ! compute the dimensions here
nR = ...
nTH = ...
call allocate_stuff(nP, nR, nTH)
call readinp()
call velderiv()
end program MainPRSCAV8f

module work_routines
real :: xbys(nP,nR,nTH), rbys(nP,nR,nTH), theta(nP,nR,nTH)
contains
subroutine allocate_stuff(nP, nR, nTH)
implicit none
integer, intent(in) :: nP, nR, nTH
allocate(xbys(nP,nR,nTH),rbys(nP,nR,nTH),theta(nP,nR,nTH))
end allocate_stuff
subroutine readinp()
implicit none
...
end subroutine readinp
subroutine velderiv()
implicit none
...
end subroutine velderiv
end module work_routines

As I said before, there are a lot of ways to do this. Your approach
is the most complicated, most error prone, and the hardest to
maintain in the future. You are using an f95 compiler, so why not
let the compiler take care of all of the details?

$.02 -Ron Shepard

Ron Shepard

unread,
Apr 6, 2009, 1:11:41 PM4/6/09
to
In article <ron-shepard-8A97...@forte.easynews.com>,
Ron Shepard <ron-s...@NOSPAM.comcast.net> wrote:

> module work_routines
> real :: xbys(nP,nR,nTH), rbys(nP,nR,nTH), theta(nP,nR,nTH)
> contains

Oops, this was a copy and paste mistake. It should have been

module work_routines
real, allocatable :: xbys(:,:,:), rbys(:,:,:), theta(:,:,:)
contains
...

$.02 -Ron Shepard

Louis Krupp

unread,
Apr 6, 2009, 2:19:04 PM4/6/09
to

You can only dimension arrays passed as arguments with nPlns, etc. You
can't use variables like nPlns to dimension local arrays or arrays in
COMMON.

Declare *all* of your arrays in the main program with maximum (maximal?)
dimensions, compute the working dimensions, and pass arrays and working
dimensions as needed. Your original problem was that you were
populating an array declared with maximum dimensions and then referring
to elements in a subroutine where the array was declared with different,
working dimensions. Don't do that.

I know you don't want to pass arrays everywhere. I know you'd rather
put them in COMMON. It doesn't matter what you want -- or what I want.
If it doesn't work, it doesn't work.

You could always join the 21st century and follow Ron Shepard's
suggestion, but you'll have to follow it carefully. Once you have
something that works, you can try to change it if you think you can make
the code more elegant.

Louis


James Van Buskirk

unread,
Apr 6, 2009, 7:23:05 PM4/6/09
to
"Louis Krupp" <lkrupp...@pssw.com.invalid> wrote in message
news:49da...@news.x-privat.org...

> You can only dimension arrays passed as arguments with nPlns, etc. You
> can't use variables like nPlns to dimension local arrays or arrays in
> COMMON.

The above is incorrect. The O.P.'s problem is that he is
attempting to use dummy arguments to dimension arrays in COMMON.
If he were using dummy arguments to dimension local arrays it would
have worked because he is using g95. I don't think g95 has a switch
to enforce f77 compatibility.

monir

unread,
Apr 7, 2009, 1:29:24 AM4/7/09
to
On Apr 6, 1:11 pm, Ron Shepard <ron-shep...@NOSPAM.comcast.net> wrote:
> In article <ron-shepard-8A979B.12051806042...@forte.easynews.com>,

>  Ron Shepard <ron-shep...@NOSPAM.comcast.net> wrote:
>
> > module work_routines
> >    real :: xbys(nP,nR,nTH), rbys(nP,nR,nTH), theta(nP,nR,nTH)
> > contains
>
> Oops, this was a copy and paste mistake.  It should have been
>
> module work_routines
>    real, allocatable :: xbys(:,:,:), rbys(:,:,:), theta(:,:,:)
> contains
> ...
>
> $.02 -Ron Shepard

Ron;

1) It was very kind of you to take the time to provide an illustration
of how you would do it in F90. Two problems however:
First: your illustration applies to the simplified, abbreviated,
modified version provided earlier in my replies. Consequently, I'm
unable to successfully tailor your illustration to the actual code.
Second: your professional code reads as foreign language of which I
don't even know its alphabet!!

2) You correctly stated: "you are making this much, much, more


complicated than it needs to be."

I agree! Not only that, but I've also confused myself in the process
of simplifying the sample code (for posting) as well as trying to
implement some of the suggestions provided herein which I thought
might work.

3) So please bear with me and let me re-describe what I'm trying to do
and why.

The *actual* program provided below (stripped down to its critical
parts) works fine with the following caveats:
a) the actual dimensions of the arrays:
....nRdim, nTHdim, nPlanes


are computed in sub ReadInp.

b) in order to dimension the local arrays throughout I had to use


Parameter statements in the main program and subprograms to set the

maximum anticipated array sizes:
....maxPln, maxR, maxTH

c) the program compiles fine as long as:
....nPlanes<=maxPln, nRdim<=maxR, nTHdim<=maxTH

d) The program would ONLY work properly if, and only if:
....maxPln=nPlanes, maxR=nRdim, maxTH=nTHdim

e) To ensure that:
+ Set reasonable values for: maxPln, maxR, maxTH in the Parameter
statements
+ Compile & run the program (realizing it wouldn't run correctly)
+ Take note of the computed values: nPlanes, nRdim, nTHdim.
+ Reset the fixed constants in the Parameter statements throughout
+ Recompile & re-run.

4) So if I can somehow dimension ALL program arrays based on the
integer variables nRdim, nTHdim, nPlanes (computed in sub ReadInp)
then there'll be no need for the Parameter statements, setting/re-
setting max values, re-compiling, re-running, etc.
So far, all my attempts (F77) for the last week or so have failed !!

5) If it's too time consuming or too much work involved, then please
just provide me with one or two small sections of the actual code
(below) converted to F90 and I'll carefully try to follow your
instructions.

6) Will treat the converted code as a black box! If it works fine and
as desired, then I'll gradually convert to F90 for good as per the
advice of Richard Maine, Louis Krupp, James Van Buskirk (and others):


"You could always join the 21st century and follow Ron Shepard's

suggestion".

Thank you again for your tremendous help.
Monir

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
PROGRAM PRSCAV8d_Original
! works Fine (F77, g95) as per item 3 a-e above

PARAMETER (maxpln=10, maxR=10, maxTH=30)

DIMENSION xbys(maxpln,maxR,maxTH), rbys(maxpln,maxR,maxTH)
DIMENSION theta(maxpln,maxR,maxTH)
DIMENSION vxbyu(maxpln,maxR,maxTH), vrbyu(maxpln,maxR,maxTH)
DIMENSION vthbyu(maxpln,maxR,maxTH)
DIMENSION dvxbyx(maxpln,maxR,maxTH),dvxbyr(maxpln,maxR,maxTH)
DIMENSION dvxbyth(maxpln,maxR,maxTH)
DIMENSION dvrbyx(maxpln,maxR,maxTH),dvrbyr(maxpln,maxR,maxTH)
DIMENSION dvrbyth(maxpln,maxR,maxTH),dvrbyrth(maxpln,maxR,maxTH)
DIMENSION dvthbyx(maxpln,maxR,maxTH),dvthbyr(maxpln,maxR,maxTH)
DIMENSION dvthbyth(maxpln,maxR,maxTH),dvthbyrth(maxpln,maxR,maxTH)
DIMENSION dcpbyx(maxpln,maxR,maxTH),dcpbyr(maxpln,maxR,maxTH)
DIMENSION dcpbyth(maxpln,maxR,maxTH)

COMMON /ABSCISAE/ xbys,rbys,theta
COMMON /VVALUES/ vxbyu,vrbyu,vthbyu
COMMON /DVELOC/ dvxbyx,dvxbyr,dvxbyth,dvrbyx,dvrbyr,
* dvrbyth,dvrbyrth,dvthbyx,dvthbyr,dvthbyth,dvthbyrth
COMMON /DCP/ dcpbyx,dcpbyr,dcpbyth
COMMON /DIM/ nRdim,nTHdim,nPlanes

!...myCode1......
CALL ReadInp
CALL VelDeriv
!...myCode2......
CALL DCpOnPln
!...myCode3......
END

C ****************************************************************
SUBROUTINE ReadInp
C ****************************************************************

PARAMETER (maxPln=10, maxR=10, maxTH=30)

INTEGER i,j,k
INTEGER NRECORDS, NPOINTS, NRDIM, NTHDIM
DIMENSION vxbyu(maxpln,maxR,maxTH), vrbyu(maxpln,maxR,maxTH)
DIMENSION vthbyu(maxpln,maxR,maxTH), vthind(maxpln,maxR,maxTH)
DIMENSION xbys(maxpln,maxR,maxTH), rbys(maxpln,maxR,maxTH)
DIMENSION theta(maxpln,maxR,maxTH)
DIMENSION TIMAST(maxPln), INDEX(maxPln)

COMMON /VVALUES/ vxbyu,vrbyu,vthbyu
COMMON /ABSCISAE/ xbys,rbys,theta
COMMON /DIM/ nRdim,nTHdim,nPlanes
COMMON /LST1/ CONFIG
COMMON /LST2/ DIAM, RPM, U, XH, NBLADE, DLAMBDA
COMMON /PARM/rad

!...myCode4......
nTHdim = ...
nRdim = ...
NPlanes = ...

!...myCode5......
CALL ARRANGE

Return
End

C ****************************************************************
SUBROUTINE ARRANGE
C ****************************************************************

PARAMETER (maxpln=10, maxR=10, maxTH=30)

INTEGER i,j,k
DIMENSION vxbyu(maxpln,maxR,maxTH), vrbyu(maxpln,maxR,maxTH)
DIMENSION vthbyu(maxpln,maxR,maxTH)
DIMENSION xbys(maxpln,maxR,maxTH), rbys(maxpln,maxR,maxTH)
DIMENSION theta(maxpln,maxR,maxTH)
DIMENSION TEMPVX(30), TEMPVR(30), TEMPVT(30) !largest of maxPln,
maxR, maxTH
DIMENSION TEMPX(30), TEMPR(30), TEMPT(30)
DIMENSION WKSP(30), IWKSP(30)

COMMON /VVALUES/ vxbyu,vrbyu,vthbyu
COMMON /ABSCISAE/ xbys,rbys,theta
COMMON /DIM/ nRdim,nTHdim,nPlanes

!...myCode6......
CALL SORT4(nplanes, TEMPX, TEMPR, TEMPT,
1 TEMPVX, TEMPVR, TEMPVT, WKSP, IWKSP)
!...myCode7......

Return
End

c ************************************************************
SUBROUTINE DCpOnPln
c ************************************************************
PARAMETER (maxpln=10, maxR=10, maxTH=30)

DIMENSION dcpbyx(maxpln,maxR,maxTH),dcpbyr(maxpln,maxR,maxTH)
DIMENSION dcpbyth(maxpln,maxR,maxTH)
DIMENSION vxbyu(maxpln,maxR,maxTH), vrbyu(maxpln,maxR,maxTH)
DIMENSION vthbyu(maxpln,maxR,maxTH)
DIMENSION dvxbyx(maxpln,maxR,maxTH),dvxbyr(maxpln,maxR,maxTH)
DIMENSION dvxbyth(maxpln,maxR,maxTH)
DIMENSION dvrbyx(maxpln,maxR,maxTH),dvrbyr(maxpln,maxR,maxTH)
DIMENSION dvrbyth(maxpln,maxR,maxTH),dvrbyrth(maxpln,maxR,maxTH)
DIMENSION dvthbyx(maxpln,maxR,maxTH),dvthbyr(maxpln,maxR,maxTH)
DIMENSION dvthbyth(maxpln,maxR,maxTH),dvthbyrth(maxpln,maxR,maxTH)
DIMENSION xbys(maxpln,maxR,maxTH), rbys(maxpln,maxR,maxTH)
DIMENSION theta(maxpln,maxR,maxTH)

COMMON /ABSCISAE/ xbys,rbys,theta
COMMON /VVALUES/ vxbyu,vrbyu,vthbyu
COMMON /DVELOC/ dvxbyx,dvxbyr,dvxbyth,dvrbyx,dvrbyr,
* dvrbyth,dvrbyrth,dvthbyx,dvthbyr,dvthbyth,dvthbyrth
COMMON /DCP/ dcpbyx,dcpbyr,dcpbyth
COMMON /DIM/ nRdim,nTHdim,nPlanes

!...myCode8......
END

c ************************************************************
SUBROUTINE VelDeriv
c ************************************************************
PARAMETER (maxpln=10, maxR=10, maxTH=30)

REAL PI,rad
DIMENSION xbys(maxpln,maxR,maxTH), rbys(maxpln,maxR,maxTH)
DIMENSION theta(maxpln,maxR,maxTH)
DIMENSION xd(30), yd(30) !!largest of maxPln, maxR, maxTH
DIMENSION vxbyu(maxpln,maxR,maxTH), vrbyu(maxpln,maxR,maxTH)
DIMENSION vthbyu(maxpln,maxR,maxTH)
DIMENSION dvxbyx(maxpln,maxR,maxTH),dvxbyr(maxpln,maxR,maxTH)
DIMENSION dvxbyth(maxpln,maxR,maxTH)
DIMENSION dvrbyx(maxpln,maxR,maxTH),dvrbyr(maxpln,maxR,maxTH)
DIMENSION dvrbyth(maxpln,maxR,maxTH),dvrbyrth(maxpln,maxR,maxTH)
DIMENSION dvthbyx(maxpln,maxR,maxTH),dvthbyr(maxpln,maxR,maxTH)
DIMENSION dvthbyth(maxpln,maxR,maxTH),dvthbyrth(maxpln,maxR,maxTH)

COMMON /ABSCISAE/ xbys,rbys,theta
COMMON /VVALUES/ vxbyu,vrbyu,vthbyu
COMMON /DVELOC/ dvxbyx,dvxbyr,dvxbyth,dvrbyx,dvrbyr,
*
dvrbyth,dvrbyrth,dvthbyx,dvthbyr,dvthbyth,dvthbyrth
COMMON /DIM/ nRdim,nTHdim,nPlanes

DATA PI /3.141592654/

!...myCode9......
CALL CALCDERIV(xd, yd, nrdim, rbys(i,j,k), dvxbyr(i,j,k))
!...myCode10.....

Return
End

c ************************************************************
SUBROUTINE DCpZeros
c ************************************************************

PARAMETER (maxpln=10, maxR=10, maxTH=30, tol=1.E-7)

DIMENSION xbys(maxpln,maxR,maxTH), rbys(maxpln,maxR,maxTH)
DIMENSION theta(maxpln,maxR,maxTH)
DIMENSION rgrid(maxR), tgrid(maxTH)
DIMENSION vxgrid(maxR,maxTH)
DIMENSION vrgrid(maxR,maxTH),vtgrid(maxR,maxTH)
EXTERNAL DCPVAL
REAL cpyzero(2,2),cpzzero(2,2)
REAL crossing(2,3),denominator
REAL RO
LOGICAL cross1, cross2
INTEGER n
INTEGER class
DIMENSION vxbyu(maxpln,maxR,maxTH), vrbyu(maxpln,maxR,maxTH)
DIMENSION vthbyu(maxpln,maxR,maxTH)
DIMENSION xcrt(30),ycrt(30) !!largest of maxPln, maxR, maxTH
DIMENSION dcpbyx(maxpln,maxR,maxTH),dcpbyr(maxpln,maxR,maxTH)
DIMENSION dcpbyth(maxpln,maxR,maxTH)

COMMON /VVALUES/ vxbyu,vrbyu,vthbyu
COMMON /ABSCISAE/ xbys,rbys,theta
COMMON /CRT/ xcrt,ycrt,n
COMMON /DCP/ dcpbyx,dcpbyr,dcpbyth
COMMON /DIM/ nRdim,nTHdim,nPlanes
COMMON /LST2/ DIAM, RPM, U, XH, NBLADE, DLAMBDA
COMMON /PARM/rad

!...myCode11.....
CALL NewP
cpyzero(2,1) = ZBRENT(DCPVAL,theta(i,j+1,k),
* theta(i,j+1,k+1),tol)
call polin2
(rgrid,tgrid,vxgrid,nrdim,nthdim,Rp,THp,vxcentre,accx)
!...myCode12.....

Return
End

C ****************************
FUNCTION dcpval(X)
C ****************************
REAL x, y, Y2A(30), d1, dn
INTEGER n
DIMENSION XA(30),YA(30)

COMMON /CRT/XA,YA,n

!...myCode13.....
CALL DERIVPOL(XA, YA, 3, XA(1), d1)
CALL SPLINE(XA, YA, n, d1, dn, Y2A)
CALL SPLINT(XA, YA, Y2A, n, x, y)
!...myCode14.....

Return
End

C ****************************************************************
SUBROUTINE NewP
C ****************************************************************

COMMON /DIM/ nRdim,nTHdim,nPlanes
COMMON /LST1/ CONFIG
COMMON /LST2/ DIAM, RPM, U, XH, NBLADE, DLAMBDA

!...myCode15.....
Return
End

C ****************************************************************
SUBROUTINE POLINT(xa, ya, n, x, y, dy)
SUBROUTINE POLIN2 (x1a, x2a, ya, m, n, x1, x2, y, dy)
SUBROUTINE RATINT(xa, ya, n, x, y, dy)
FUNCTION ZBRENT(func, x1, x2, tol)
SUBROUTINE POLCOF (XA, YA, N, COF)
SUBROUTINE DDPOLY (C, NC, X, PD, ND)
SUBROUTINE DERIVPOL (xa, ya, n, x, dy)
SUBROUTINE SPLINE(X, Y, N, YP1, YPN, Y2)
SUBROUTINE SPLINT(XA, YA, Y2A, N, X, Y)
SUBROUTINE SPLDERIV(XA, YA, Y2A, N, X, DY)
SUBROUTINE CALCDERIV (XA, YA, N, x, dy)
SUBROUTINE INDEXX (N, ARRIN, INDX)
SUBROUTINE SORT4 (N, RA, RB, RC, RD, RE, RF, WKSP, IWKSP)
C ****************************************************************

Louis Krupp

unread,
Apr 7, 2009, 7:50:47 AM4/7/09
to
James Van Buskirk wrote:
> "Louis Krupp" <lkrupp...@pssw.com.invalid> wrote in message
> news:49da...@news.x-privat.org...
>
>> You can only dimension arrays passed as arguments with nPlns, etc. You
>> can't use variables like nPlns to dimension local arrays or arrays in
>> COMMON.
>
> The above is incorrect. The O.P.'s problem is that he is
> attempting to use dummy arguments to dimension arrays in COMMON.
> If he were using dummy arguments to dimension local arrays it would
> have worked because he is using g95. I don't think g95 has a switch
> to enforce f77 compatibility.
>

One of the O.P.'s posts (Fri, 3 Apr 2009 21:26:13 -0700 (PDT)) seemed to
indicate otherwise:

===

****************************************************************
Subroutine PRSCAV8e (nPlanes, nRdim, nTdim)
C
****************************************************************
Dimension xbys (nPlanes,nRdim,nTdim), rbys(nPlanes,nRdim,nTdim) !

Compiler error

...

The following Compiler Error message is displayed (reference to the

1st arg in the 1st dim statement in sub PRSCAV8e):


"Error: Array bound at (nPlanes) must be constant"

===

It's possible that he put the array in COMMON and didn't show that bit
of code.

Louis

Richard Maine

unread,
Apr 7, 2009, 11:24:39 AM4/7/09
to
Louis Krupp <lkrupp...@pssw.com.invalid> wrote:

> James Van Buskirk wrote:
> > "Louis Krupp" <lkrupp...@pssw.com.invalid> wrote in message
> > news:49da...@news.x-privat.org...
> >
> >> You can only dimension arrays passed as arguments with nPlns, etc. You
> >> can't use variables like nPlns to dimension local arrays or arrays in
> >> COMMON.
> >
> > The above is incorrect. The O.P.'s problem is that he is
> > attempting to use dummy arguments to dimension arrays in COMMON.
> > If he were using dummy arguments to dimension local arrays it would
> > have worked because he is using g95. I don't think g95 has a switch
> > to enforce f77 compatibility.
>
> One of the O.P.'s posts (Fri, 3 Apr 2009 21:26:13 -0700 (PDT)) seemed to
> indicate otherwise:

...


> Subroutine PRSCAV8e (nPlanes, nRdim, nTdim)

...


> Dimension xbys (nPlanes,nRdim,nTdim), rbys(nPlanes,nRdim,nTdim) !

...


> "Error: Array bound at (nPlanes) must be constant"
>

> It's possible that he put the array in COMMON and didn't show that bit
> of code.

For "possible" substitute "extremely likely". It certainly seems far
more likely than that g95 has some such undocumented switch and that the
OP managed to turn it on. The docs don't even show a switch for f90,
much less f77; the options documented are f95 and f2003.

Note that the OP claimed to be showing the "relevant" bits of code. Take
home another case of the lesson pretty regularly illustrated here: when
someone is asking for help, particularly help on things at this fairly
basic level (failing to understand that a dummy argument is not a
constant, regardless of the actual argument, is fairly basic), that
person is likely to be a poor judge of what bits are relevant. That's
why it is common to insist on seeing actual complete examples instead of
"relevant bits".

monir

unread,
Apr 8, 2009, 12:18:08 PM4/8/09
to
On Apr 7, 11:24 am, nos...@see.signature (Richard Maine) wrote:

> Louis Krupp <lkrupp_nos...@pssw.com.invalid> wrote:
> > James Van Buskirk wrote:
> > > "Louis Krupp" <lkrupp_nos...@pssw.com.invalid> wrote in message
> > >news:49da...@news.x-privat.org...
>
Hi;

I suppose if F90 is using Modules to provide global access to data
instead of F77 Common blocks, then for those who would be kind enough
to help and respond to my latest post (Apr 7, 1:29 am, where I
provided an abbreviated stripped-down version of my *actual* F77
working program):

1) Wouldn't you be interested in knowing where each of the current
common blocks is filled (for lack of a better word!) ?? and
Which program units share its variables ??
Or that is irrelevant since I provided earlier the list of the Common
blocks in the main program and in each of the subprograms!

2) In any event, the following simple table helps (me) to clarify the
structure of the program and the dataflow regarding the common blocks
for possible future changes:
(I hope the table format wouldn't be distorted in the process of
posting!)

=Comm Block==Its Variables=====Shared by=====
====Name======Computed in=====Program Units==
ABSCISAE........ReadInp.......main, ARRANGE,
..............................DcpOnPln, VelDeriv,
..............................DCpZeros
VVALUES.........ReadInp.......main, ARRANGE,
..............................DcpOnPln, VelDeriv,
..............................DCpZeros
DIM.............ReadInp.......main, ARRANGE,
..............................DcpOnPln, VelDeriv,
..............................DCpZeros, NewP
LST1............ReadInp.......NewP
LST2............ReadInp.......DcPZeros, NewP
PARM............ReadInp.......DcPZeros
DVELOC..........VelDeriv......main, DcpOnPln
DCP.............DcpOnPln......main, DCpZeros
CRT.............DCpZeros......Fun dcpval

Regards.
Monir

Ron Shepard

unread,
Apr 8, 2009, 1:14:04 PM4/8/09
to
In article
<3e345e8d-9041-45f8...@f18g2000vbf.googlegroups.com>,
monir <mon...@mondenet.com> wrote:

> 1) Wouldn't you be interested in knowing where each of the current
> common blocks is filled (for lack of a better word!) ?? and
> Which program units share its variables ??

I doubt that any posters here will make the effort to rewrite your
program for you.

However, if you do want to convert your code from common blocks to
modules, I can suggest the following steps.

0) Start with a working program that uses common blocks. Print out
enough information so that you will be able to compare changes in
the output line by line with future modified versions.

1) Move all subprograms into one or more modules (so that they will
have explicit interfaces), and use IMPLICIT NONE throughout (so you
can track local and common variable names easily).

2) Make sure that all declarations of each common block use the same
variable list (in the same order, of course).

3) For each common block (or perhaps a small group of related common
blocks), create a module that includes that common block, and
nothing else.

4) Replace each local declaration of the common block (and its
variables) with a use statement. After each replacement, verify
that your program still computes correct results. This can be done
one at a time, or it can be done in small groups to try to save some
time.

5) After all local declarations of common blocks have been removed
in the main program and all subprograms, you can then eliminate the
common blocks in each of the modules by replacing them with module
variables with the same variable names. Do this one module at a
time, and verify the program is correct after each change.

6) After all common blocks have been eliminated throughout your
program (i.e. all local declarations have been removed and no common
blocks exist in the modules), you can them make the arrays
allocatable. Write a routine whose task is to allocate the arrays
with the correct dimensions, which you determine at runtime.

7) Now you have a working program with fully dynamic runtime
allocation of your arrays. You might want to review the modules and
perhaps combine the variables in some of them, or maybe even split
off the variables into separate modules in others.

Another general change you might want to make is to group the module
variables together with the closely related routines that modify
those variables. This is object-oriented programming. It isn't
necessary, but it sometimes simplifies the program structure and
facilitates future maintenance and code reusability.

This approach allows you to make small incremental changes to your
code, testing and verifying at each step along the way, and to
transform your code from a difficult to understand and maintain f77
program with static memory allocation to a modern, easy to
understand and maintain, f90 version of your program with flexible
runtime memory allocation.

$.02 -Ron Shepard

monir

unread,
Apr 8, 2009, 4:55:34 PM4/8/09
to
On Apr 8, 1:14 pm, Ron Shepard <ron-shep...@NOSPAM.comcast.net> wrote:
> In article
> <3e345e8d-9041-45f8-885e-9f4e3fd75...@f18g2000vbf.googlegroups.com>,

Ron;

1) Sorry if I had left the impression that someone would convert the
F77 program to F90 for me!!!
That certainly was NOT my intention.
I thought a few lines of code based on the (provided) *actual* F77
abbreviated main program and one of its subprogram, probably totalling
15 - 20 lines of F90 code (analogous to your earlier illustration)
would be sufficient for me to get started!

2) In any event, your latest step-by-step approach is clear and very
precise, and quite honestly far exceeded my expectation!
I'll carefully follow your instructions and report back at some point.

3)You and other Fortran experts have persistently made it clear:
"... forget about F77 and convert to F90/F95"

OK. Based on your (and others) experience:
a) Is it a good idea to jump from F77 to F95 standard ??
or, it would be a huge leap and better learn F90 first then F95 ??
I'm assuming F90 builds on F77 and F95 on F90. Correct ??
Is F08 the latest "working" Fortran standard currently in use ??
(just curiosity, I wouldn't go that far anyway !!)

b) What is your preferred Ref. book or "free" accessible site to
consult when the need arises ??
(a Ref. with the basic Standard features and a lot of examples or how-
to.)

Thank you again for your time and help. Greatly appreciated!
Monir

dpb

unread,
Apr 8, 2009, 5:22:10 PM4/8/09
to
monir wrote:
...

> OK. Based on your (and others) experience:
> a) Is it a good idea to jump from F77 to F95 standard ??
> or, it would be a huge leap and better learn F90 first then F95 ??
> I'm assuming F90 builds on F77 and F95 on F90. Correct ??

There's essentially no difference in F90/95--F95 "only" fixed a major
issue w/ implementation concerning ALLOCATABLE in F90 and added a couple
minor things.

As for the "building on" there are only a very few things in F77 that
aren't in F95 (or in F08 for that matter) so, the answer there is
unequivocally "yes".

--

Richard Maine

unread,
Apr 8, 2009, 5:25:48 PM4/8/09
to
monir <mon...@mondenet.com> wrote:

> OK. Based on your (and others) experience:
> a) Is it a good idea to jump from F77 to F95 standard ??
> or, it would be a huge leap and better learn F90 first then F95 ??

No. The differences between f90 and f95 are trivial compared to those
between f77 and f90 or f95. F95 is a pretty minor tweak on f90. Indeed,
the biggest changes between f90 and f95 weren't even at the level of
user features, but rather corrections and clarifications of technical
points within the standard. There were a few features added, but they
were minor and more of an add-on to the main purpose of getting the
corrections and clarifications incorporated.

I have been known to refer to f95 as f90 version 2. That is not any kind
of official or accepted designation. Don't actually try to use that term
for it, as people won't know what you mean. But I feel it captures the
flavor. You will often see people (including myself) refer to f90/f95,
which I think reasonably captures the idea that they are largely the
same thing.

> Is F08 the latest "working" Fortran standard currently in use ??

No. There are no f08 compilers. I'm not even 100% sure that f08 has
quite yet been formally published. It might have been, but I haven't
tracked it.

In fact, it is darned hard to find f2003 compilers. I've heard it
alleged that one, or maybe even two, exist, but none on any machines
that I (or you) would have access to.

F95 is pretty much the norm for what you'll find available today. Many
of today's f95 compilers have partial support for a few f2003 features,
but they aren't full f2003 compilers.

> b) What is your preferred Ref. book or "free" accessible site to
> consult when the need arises ??
> (a Ref. with the basic Standard features and a lot of examples or how-
> to.)

I often recommend Metcalf & Reid. I'm not entirely sure, however, that
it is a good match for you. Hard for me to tell. It is a bit concise,
which can be either a strength or a weakness. I like it, and I've heard
from many other people who also do, but there are some people who find
it too concise for their taste.

Cooper and Redwine is an excellent (out of print) text for transitioning
from f77 to f90 (it never got updated to an f95 version). But I'm a bit
concerned that it might assume a stronger knowledge of f77 than is
apparent here.

I have a conflict of interest relating to at least one candidate. In any
case, I couldn't honestly judge whether it would be the best choice for
you either.

So I'll abstain from recommendation. Others might do better at that.

nm...@cam.ac.uk

unread,
Apr 8, 2009, 5:42:50 PM4/8/09
to
In article <1ixuxw0.fti6vygxnqewN%nos...@see.signature>,
Richard Maine <nos...@see.signature> wrote:

>monir <mon...@mondenet.com> wrote:
>
>> Is F08 the latest "working" Fortran standard currently in use ??
>
>No. There are no f08 compilers. I'm not even 100% sure that f08 has
>quite yet been formally published. It might have been, but I haven't
>tracked it.

It hasn't. It's not even FCD yet.


Regards,
Nick Maclaren.

Ron Shepard

unread,
Apr 8, 2009, 7:08:09 PM4/8/09
to
In article <1ixuxw0.fti6vygxnqewN%nos...@see.signature>,
nos...@see.signature (Richard Maine) wrote:

> No. The differences between f90 and f95 are trivial compared to those
> between f77 and f90 or f95.

> [...]


> F95 is pretty much the norm for what you'll find available today. Many
> of today's f95 compilers have partial support for a few f2003 features,
> but they aren't full f2003 compilers.

There is a major defect in f95 related to allowing allocatable arrays as
dummy arguments and as members of user defined types. IMO, f95 should
not have been approved and finalized until this important feature had
been included. This was the single most important feature beyond f90
that was supposed to have been in the next standard. But, that is not
the way it happened. Instead, there was an ISO Technical Report
(TR-15581) released shortly after final f95 approval, and before most
f95 compilers had arrived, that fixed the limitations with f90 and f95.
So for many vendors, their first "f95" compiler was really f95+TR-15581.
If the f95 approval process had been done the right way and included
this in the standard itself, we would not have to worry about this
distinction now, 19 years later. Or if there had been an f96 or f97
that included this, we wouldn't have to worry about it now, but that
didn't happen either.

I would say now that it is safe to assume that the current "fortran"
from any vendor means f95+TR-15581. This includes gfortran and g95, the
two free compilers based on GCC. Or said another way, if a vendor
claims f95 but does not support TR-15581, he is technically correct but
he is dragging his feet. So if you use these allocatable array
features, you can be reasonably confident that current compilers support
it. That is not true for some of the new features in f2003. So for
right now, if you want to write portable code (meaning code that you
compile with a wide variety of compilers, or that many other people
compile with their compiler), I would say that f95+TR-15581 is safe, but
f2003 isn't.

$.02 -Ron Shepard <--IMO, of course

Richard Maine

unread,
Apr 8, 2009, 7:23:32 PM4/8/09
to
Ron Shepard <ron-s...@NOSPAM.comcast.net> wrote:

> I would say now that it is safe to assume that the current "fortran"
> from any vendor means f95+TR-15581.

Good point.

But I think you underestimate the work that was involved in getting that
feature first into the standard and then into compilers. It was not just
a matter of waving a wand and declaring it to happen, and it wasn't
omitted from f95 because people didn't want it in.

It was omitted from f95 because, in spite of people working quite a bit
on it, the specification just wasn't ready yet. Several quite
significant problems with the specification were fixed over the next
several years. Even once the TR was released, it took quite a long time
for vendors to get it implemented and at least more-or-less working
correctly. Early implementations tended to be awfully buggy, and in this
case "early" lasted quite a while.

It looks like it ought to have been so simple and trivial. But it
wasn't.

I agree that we are past that point today, and in particular I would
agree with:

> Or said another way, if a vendor
> claims f95 but does not support TR-15581, he is technically correct but

--

Ron Shepard

unread,
Apr 9, 2009, 12:51:04 PM4/9/09
to
In article <1ixv3s8.1y297eg17rp1xcN%nos...@see.signature>,
nos...@see.signature (Richard Maine) wrote:

> But I think you underestimate the work that was involved in getting that
> feature first into the standard and then into compilers. It was not just
> a matter of waving a wand and declaring it to happen, and it wasn't
> omitted from f95 because people didn't want it in.
>
> It was omitted from f95 because, in spite of people working quite a bit
> on it, the specification just wasn't ready yet. Several quite
> significant problems with the specification were fixed over the next
> several years. Even once the TR was released, it took quite a long time
> for vendors to get it implemented and at least more-or-less working
> correctly. Early implementations tended to be awfully buggy, and in this
> case "early" lasted quite a while.

Maybe my memory is off. When was f95 approved, and when was the TR
published? I thought the TR was just a short time after f95?

This is the same kind of situation we had with f77 and the
mil-std-1754 standard. The mil standard was published shortly after
f77 was approved, and well before there were many f77 compilers.
The mil standard had some important stuff that should have been
included either in f77 itself, or in a minor revision shortly
thereafter. After all, how complicated would it have been to
include IMPLICIT NONE into the language. Everyone wanted it, there
wasn't really any opposition to the feature. But that didn't
happen, and we were stuck with things like nonportable bit operators
(and no IMPLICIT NONE) for over 15 years years because of that.

In the case of the allocatable TR, it also (if my memory is right)
was published soon after f95 was approved, it had some important
stuff that should have been implemented either in f95 itself (either
by focusing more effort on it, or by waiting a few months) or in a
minor revision shortly thereafter. As recently as three years ago I
was not comfortable using those features in my fortran codes because
of a lack of portability. It has only been since then that I've
become comfortable enough with the portability of the features to
use them. The alternative, pointer arrays, is unsatisfactory for
several reasons. The main delay, as far as the standards process,
has not been implementation of the TR features (most current
compilers do support those now), it is because f2003 includes not
only the allocatable features but a whole truckload of other things.

Hindsight is 20/20, but if everyone knew back in the early 90's that
if the allocatable array features would not be added to the standard
for another 10 years (f2003), and that it would take another 5 to 10
years after that before f2003 compilers would become commonly
available, then I think everyone would have agreed that the best
thing would be to focus on getting it into f95 rather than waiting.
Maybe everyone thought that if it didn't make f95, then it would
make it in a revision soon afterwards, say 1997 or 1998. If that
had happened, then it would not have been a big deal. But waiting
for a feature as important as that for 14 years (or 19 years, if you
count from f90 rather than f95) is a long time.

$.02 -Ron Shepard

Richard Maine

unread,
Apr 9, 2009, 1:16:48 PM4/9/09
to
Ron Shepard <ron-s...@NOSPAM.comcast.net> wrote:

> In article <1ixv3s8.1y297eg17rp1xcN%nos...@see.signature>,
> nos...@see.signature (Richard Maine) wrote:
>
> > But I think you underestimate the work that was involved in getting that
> > feature first into the standard and then into compilers. It was not just
> > a matter of waving a wand and declaring it to happen, and it wasn't
> > omitted from f95 because people didn't want it in.
> >
> > It was omitted from f95 because, in spite of people working quite a bit
> > on it, the specification just wasn't ready yet. Several quite
> > significant problems with the specification were fixed over the next
> > several years. Even once the TR was released, it took quite a long time
> > for vendors to get it implemented and at least more-or-less working
> > correctly. Early implementations tended to be awfully buggy, and in this
> > case "early" lasted quite a while.
>
> Maybe my memory is off. When was f95 approved, and when was the TR
> published? I thought the TR was just a short time after f95?

I forget the exact publication dates. Not worth looking up. They don't
tell the whole story anyway. I was helping work on some of the stuff and
I recall much more than those dates would tell. The timeline for
publishing a TR is *MUCH* shorter than for a standard. So even if they
were published almost simultaneously (as was the case with f2003 and the
submodule TR), that could mean they were a year or even two apart in the
technical work having been done.

I also think I recall that the first version of the TR still had
significant errors, illustrating, I think, that it was rushed out
without as much study as it really ought to have had. I think I recall a
revision of the TR, though I might be confusing it with something else.

I do know that even after the TR (and the revision if I recall
correctly), there were *STILL* oversights found. Perhaps not exactly
errors, but things that weren't as well integrated as they should have
been. Some of that was addressed in f2003. See the allocatable character
stuff. That wasn't really a separate feature done as a new thing on its
own; it was more a metter of better integrating what was done before.
And darned if there aren't bits that have come up even after f2003 as
not quite "right". Seeing all of this has been an enlightening process.
Quote publication dates all you want, but I recall a long process with
many iterations of infelicities being found.

Vendors knew about the TR from before when f95 was published. The thing
that kept the features out of some of the compilers wasn't that the
material wasn't in the base standard. It was that it was hard to
implement well. Note all the compilers that did have it in, but were
full of bugs relating to it... for quite a long time. Being in the base
standard wouldn't have fixed that. It would have made it worse if the
version in the base standard was rushed enough to be broken enough to
need substantial rework.

> Hindsight is 20/20, but if everyone knew back in the early 90's that
> if the allocatable array features would not be added to the standard
> for another 10 years (f2003), and that it would take another 5 to 10
> years after that before f2003 compilers would become commonly
> available, then I think everyone would have agreed that the best
> thing would be to focus on getting it into f95 rather than waiting.
> Maybe everyone thought that if it didn't make f95, then it would
> make it in a revision soon afterwards, say 1997 or 1998. If that
> had happened, then it would not have been a big deal. But waiting
> for a feature as important as that for 14 years (or 19 years, if you
> count from f90 rather than f95) is a long time.

I disagree with most of this. People did consider it really important to
get the allocatable stuff out quickly. That was *EXACTLY* why it was
done in a TR - because that would get it out more quickly than waiting
for a next revision of the standard. That part doesn't require hindsight
- at least not as far as f95 goes. I can't speak for f90, but I was
there and part of the decision process for f95. I know that it was put
in a TR to facilitate it getting out faster because of its importance. I
see nothing in hindsight that differs from what I recall being seen in
foresight, except that the whole thing was harder than anticipated.

Phillip Helbig---remove CLOTHES to reply

unread,
Apr 9, 2009, 4:36:50 PM4/9/09
to
In article <1ixuxw0.fti6vygxnqewN%nos...@see.signature>,
nos...@see.signature (Richard Maine) writes:

> > Is F08 the latest "working" Fortran standard currently in use ??
>

> No. There are no f08 compilers. I'm not even 100% sure that f08 has
> quite yet been formally published. It might have been, but I haven't
> tracked it.
>

> In fact, it is darned hard to find f2003 compilers. I've heard it
> alleged that one, or maybe even two, exist, but none on any machines
> that I (or you) would have access to.
>

> F95 is pretty much the norm for what you'll find available today. Many
> of today's f95 compilers have partial support for a few f2003 features,
> but they aren't full f2003 compilers.

Why is that?

I did a lot of Fortran programming with VAX FORTRAN and DEC Fortran,
Fortran 77, Fortran 90 and Fortran 95, on VAX and ALPHA machines running
VMS. Unfortunately, Fortran on VMS is more or less frozen. Sic transit
gloria mundi. I had put this down to the general change (mostly for the
worse) when VMS failed to stay on in the academic world (where it once
reigned supreme) and concentrated more on well paying customers (of
which there are many, at least in terms of generated revenue, but
Fortran is not the language of choice, but rather Cobol or C or C++).
However, it seems that few if any of the classic vendors (IBM, SUN, SGI,
HP) are keeping up with the Fortran standard. Why is that? If it is
because users don't need/want the new features, then who is driving the
standard development?

Paul van Delst

unread,
Apr 9, 2009, 5:08:33 PM4/9/09
to
Phillip Helbig---remove CLOTHES to reply wrote:

> However, it seems that few if any of the classic vendors (IBM, SUN, SGI,
> HP) are keeping up with the Fortran standard.

- Last time I checked (end of last year), IBM xlf2003 was almost complete except for
parameterised derived types.
- Does SGI even exist anymore? IIRC they never even released an f95 compiler and I knew
how to reliably ICE their f90 one (an older version I think).
- A Sun representative regularly posts here about their f95 and beyond product.
- Does HP still build workstations and compilers? I know there are people out there that
use 'em with some of my code which is standard f95 so I would assume so.
- Linux machines here use various incarnations of PGI, Intel, Lahey, g95, and gfortran.

glen herrmannsfeldt

unread,
Apr 9, 2009, 5:23:56 PM4/9/09
to
Paul van Delst <Paul.v...@noaa.gov> wrote:

(snip)

> - Does HP still build workstations and compilers?
> I know there are people out there that use 'em with some of
> my code which is standard f95 so I would assume so.

I believe they are still building Itanium2 machines.

There is, at least VMS and Linux available for Itanium,
and I believe still Windows 2003 and 2008.

-- glen

Phillip Helbig---remove CLOTHES to reply

unread,
Apr 9, 2009, 5:54:22 PM4/9/09
to
In article <grlp1c$ijc$1...@naig.caltech.edu>, glen herrmannsfeldt
<g...@ugcs.caltech.edu> writes:

> Paul van Delst <Paul.v...@noaa.gov> wrote:
>
> (snip)
>

> > - Does HP still build workstations and compilers?
> > I know there are people out there that use 'em with some of
> > my code which is standard f95 so I would assume so.
>

> I believe they are still building Itanium2 machines.
>
> There is, at least VMS and Linux available for Itanium,
> and I believe still Windows 2003 and 2008.

Yes, VMS on Itanium is alive and well and running some things you can
easily guess and some you can't. However, there is no modern Fortran
compiler for it.

monir

unread,
Apr 10, 2009, 3:47:45 PM4/10/09
to
Hello;

Provided below is my latest (unseccessful!) attempt to convert the F77
code to F90.

The goal once again is to dimension ALL arrays in the main program and
subprograms based on *nPlanes, nRdim, nTHdim* computed in Sub ReadInp.

The g95 compiler displayed the following error:
Fatal Error: Can't open module file 'dim.mod' at (DIM) for reading: No
such file or directory
(with ref. to DIM in the 1st Use statement in the main program)

I'm sure it's a beginner/rookie mistake! Clearly F90 is far more
complex (and appears to be more elegant) than F77.

Your help would be greatly appreciate.
Monir

c************************************************************
PROGRAM PRSCAV8d_F90_1
c************************************************************
Use DIM !fatal error. DIM maybe a reserved keyword (as e.g. in
VBA ?
use ABSCISAE
........................
integer :: nRdim,nTHdim,nPlanes

real :: xbys(nPlanes,nRdim,nTHdim),rbys(nPlanes,nRdim,nTHdim)
real :: theta(nPlanes,nRdim,nTHdim)

real :: vxbyu(nPlanes,nRdim,nTHdim),vrbyu(nPlanes,nRdim,nTHdim)
real :: vthbyu(nPlanes,nRdim,nTHdim)
........................
!...myCode1........
CALL ReadInp
CALL VelDeriv
!...myCode2........
END

Module DIM
integer :: nRdim,nTHdim,nPlanes
End Module DIM
!...
Module ABSCISAE
integer ::nRdim,nTHdim,nPlanes
real :: xbys(nPlanes,nRdim,nTHdim),rbys(nPlanes,nRdim,nTHdim)
real :: theta(nPlanes,nRdim,nTHdim)
End Module ABSCISAE
!...
Module Work_Routines

c************************************************************
SUBROUTINE ReadInp
c************************************************************
c here where nPlanes, nRdim, nTHdim are computed

use DIM
use ABSCISAE
............................
integer, allocatable :: nPlanes, nRdim, nTHdim

real :: xbys(nPlanes,nRdim,nTHdim),rbys(nPlanes,nRdim,nTHdim)
real :: theta(nPlanes,nRdim,nTHdim)
............................
!...myCode4........
NPlanes = 10 !computed
nRdim = 10
nTHdim = 30

call Allocate_Stuff (nPlanes, nRdim, nTHdim)

!...myCode5........

CALL ARRANGE

RETURN
END

c************************************************************
Subroutine Allocate_Stuff(nPlanes, nRdim, nTHdim)
c************************************************************
integer, Intent(in) :: nPlanes, nRdim, nTHdim

Allocate (nPlanes, nRdim, nTHdim)

End Allocate_Stuff

c************************************************************
SUBROUTINE ARRANGE
c************************************************************
use DIM
use ABSCISAE
............................
INTEGER i,j,k
integer :: nRdim,nTHdim,nPlanes
real :: xbys(nPlanes,nRdim,nTHdim),rbys(nPlanes,nRdim,nTHdim)
real :: theta(nPlanes,nRdim,nTHdim)

real :: vxbyu(nPlanes,nRdim,nTHdim),vrbyu(nPlanes,nRdim,nTHdim)
real :: vthbyu(nPlanes,nRdim,nTHdim)
............................
!...myCode6........
RETURN
END
!.......
End Module work_routines

Richard Maine

unread,
Apr 10, 2009, 3:56:39 PM4/10/09
to
monir <mon...@mondenet.com> wrote:

> Fatal Error: Can't open module file 'dim.mod' at (DIM) for reading: No
> such file or directory

You need to compile the module before you can use it. This is most often
done by putting the module is a separate file and compiling that
separate file first. It can alternatively be done by putting the module
prior to any uses of it in the same file.

> Use DIM !fatal error. DIM maybe a reserved keyword (as e.g. in
> VBA ?

No. Fortran has no reserved keywords. The closest thing to a reserved
word is that you can't use the name of an intrinsic type as the name of
a derived type; you can, however, use it for the name of anything else.

dpb

unread,
Apr 10, 2009, 3:57:28 PM4/10/09
to
monir wrote:
...

> The g95 compiler displayed the following error:
> Fatal Error: Can't open module file 'dim.mod' at (DIM) for reading: No
> such file or directory
> (with ref. to DIM in the 1st Use statement in the main program)
>
> I'm sure it's a beginner/rookie mistake! Clearly F90 is far more
> complex (and appears to be more elegant) than F77.
...

To USE a module, it must be compiled prior to the code that refers to
it. That's what the ".mod" file extension the compiler complained about
not finding is--the equivalent for modules of an object (.obj/.o) file
for "ordinary" code.

I didn't have time to read actual code enough to rearrange it -- the
easy/quick way would be to put the module in its own file, compile it
and then compile the rest of the code that USE's it.

--

Ron Shepard

unread,
Apr 10, 2009, 6:29:44 PM4/10/09
to
In article
<848eb928-6c9b-40ab...@q16g2000yqg.googlegroups.com>,
monir <mon...@mondenet.com> wrote:

> Provided below is my latest (unseccessful!) attempt to convert the F77
> code to F90.

This is much easier to do if you do it a step at a time rather than all
at once. However, here are some comments on your alternative
all-at-once approach.


> The goal once again is to dimension ALL arrays in the main program and
> subprograms based on *nPlanes, nRdim, nTHdim* computed in Sub ReadInp.

Ok, but that doesn't look like what your code below is trying to do.

> Module DIM
> integer :: nRdim,nTHdim,nPlanes
> End Module DIM

Why do you have this module separate? It is always used at the same
time as the next module, so that suggests that they should really be
together. I'll make that change, so that this DIM module should no
longer exist.

> !...
> Module ABSCISAE
> integer ::nRdim,nTHdim,nPlanes
> real :: xbys(nPlanes,nRdim,nTHdim),rbys(nPlanes,nRdim,nTHdim)
> real :: theta(nPlanes,nRdim,nTHdim)
> End Module ABSCISAE

You can't use variables in dimension statements here. You can for
automatic arrays (which was my first suggestion previously). For arrays
in modules, you must have allocatable arrays. You want something like
this:

Module ABSCISAE
integer :: nRdim,nTHdim,nPlanes


real, allocatable :: xbys(:,:,:),rbys(:,:,:)

real, allocatable :: theta(:,:,:)
real, allocatable :: vxbyu(:,:,:),vrbyu(:,:,:)
real, allocatable :: vthbyu(:,:,:)
End Module ABSCISAE

> !...


> c************************************************************
> PROGRAM PRSCAV8d_F90_1
> c************************************************************
> Use DIM !fatal error. DIM maybe a reserved keyword (as e.g. in

I'm assuming that all of this is all in one file. If so, then the
easiest thing to do is to put these modules first, followed by the
program and subroutines that use them. So I moved the module to the
above.

> use ABSCISAE

You also need

use Work_Routines

Personally, I would put those routines in the same module as the data,
but this is alright too. However, this module should be moved to before
the main program if it is in the same file.

> ........................
> integer :: nRdim,nTHdim,nPlanes
>
> real :: xbys(nPlanes,nRdim,nTHdim),rbys(nPlanes,nRdim,nTHdim)
> real :: theta(nPlanes,nRdim,nTHdim)
>
> real :: vxbyu(nPlanes,nRdim,nTHdim),vrbyu(nPlanes,nRdim,nTHdim)
> real :: vthbyu(nPlanes,nRdim,nTHdim)

These arrays should not be here, they are already available through the
module.

> ........................
> !...myCode1........
> CALL ReadInp
> CALL VelDeriv

This subroutine is not defined anywhere. I'll leave it in, but comment
it out below.

> !...myCode2........
> END
>
> Module Work_Routines

This should be moved to before your main program for the same reason as
above. Actually, I would probably combine the data module with these
routines, but I'll leave them separate in the code below.

>
> c************************************************************
> SUBROUTINE ReadInp
> c************************************************************
> c here where nPlanes, nRdim, nTHdim are computed
>
> use DIM

DIM no longer exists.

> use ABSCISAE
> ............................
> integer, allocatable :: nPlanes, nRdim, nTHdim
>
> real :: xbys(nPlanes,nRdim,nTHdim),rbys(nPlanes,nRdim,nTHdim)
> real :: theta(nPlanes,nRdim,nTHdim)

These arrays are now in the module, they should not be redefined or
redeclared here.

> ............................
> !...myCode4........
> NPlanes = 10 !computed
> nRdim = 10
> nTHdim = 30
>
> call Allocate_Stuff (nPlanes, nRdim, nTHdim)

call Allocate_Stuff()

You don't need these arguments, these variables are in the module.

> !...myCode5........
>
> CALL ARRANGE
>
> RETURN
> END
>
> c************************************************************
> Subroutine Allocate_Stuff(nPlanes, nRdim, nTHdim)

This is where the arrays are actually allocated. You want something
like this:

Subroutine Allocate_Stuff()
use ABSCISAE
Allocate(xbys(nPlanes,nRdim,nTHdim),rbys(nPlanes,nRdim,nTHdim), &
& theta(nPlanes,nRdim,nTHdim), &
& vxbyu(nPlanes,nRdim,nTHdim),vrbyu(nPlanes,nRdim,nTHdim), &
& vthbyu(nPlanes,nRdim,nTHdim) )
End subroutine Allocate_Stuff



> c************************************************************
> SUBROUTINE ARRANGE
> c************************************************************
> use DIM

This no longer exists.

> use ABSCISAE

This is the only USE statement you want to keep. If the data were in
the same module, then you wouldn't want this USE statement either.

> ............................
> INTEGER i,j,k

These are local variables, so keep them.

> integer :: nRdim,nTHdim,nPlanes
> real :: xbys(nPlanes,nRdim,nTHdim),rbys(nPlanes,nRdim,nTHdim)
> real :: theta(nPlanes,nRdim,nTHdim)
>
> real :: vxbyu(nPlanes,nRdim,nTHdim),vrbyu(nPlanes,nRdim,nTHdim)
> real :: vthbyu(nPlanes,nRdim,nTHdim)
> ............................

Delete all of the above declarations. These arrays are in the module.

> !...myCode6........
> RETURN
> END
> !.......
> End Module work_routines

So, in the end, the entire code should look something like the following:


Module ABSCISAE
implicit none
integer :: nRdim, nTHdim, nPlanes


real, allocatable :: xbys(:,:,:),rbys(:,:,:)

real, allocatable :: theta(:,:,:)
real, allocatable :: vxbyu(:,:,:),vrbyu(:,:,:)
real, allocatable :: vthbyu(:,:,:)
End Module ABSCISAE

Module Work_Routines
contains
SUBROUTINE ReadInp()
use ABSCISAE
implicit none


!...myCode4........
NPlanes = 10 !computed
nRdim = 10
nTHdim = 30

call Allocate_Stuff()
!...myCode5........
CALL ARRANGE()
RETURN
END SUBROUTINE ReadInp

Subroutine Allocate_Stuff()
use ABSCISAE
implicit none
Allocate( xbys(nPlanes,nRdim,nTHdim), &
& rbys(nPlanes,nRdim,nTHdim), &
& theta(nPlanes,nRdim,nTHdim), &
& vxbyu(nPlanes,nRdim,nTHdim), &
& vrbyu(nPlanes,nRdim,nTHdim), &
& vthbyu(nPlanes,nRdim,nTHdim) )
End subroutine Allocate_Stuff

SUBROUTINE ARRANGE()
use ABSCISAE
implicit none
INTEGER :: i,j,k
!...myCode6........
RETURN
END SUBROUTINE ARRANGE
End Module work_routines

PROGRAM PRSCAV8d_F90_1
use ABSCISAE
use Work_Routines
implicit none

!...myCode1........
CALL ReadInp()
!CALL VelDeriv()
!...myCode2........
END PROGRAM PRSCAV8d_F90_1

I ran this through a compiler, and apart from possible cut-and-paste or
newsreader wrapping quirks, it compiles without error, but of course it
doesn't really do anything.

If the data were moved into module Work_Routines, then all of the USE
ABSCISAE statements should be removed and the module ABSCISAE should be
deleted from the file.

$.02 -Ron Shepard

monir

unread,
Apr 10, 2009, 9:04:33 PM4/10/09
to

Richard;

Thank you kindly for your prompt reply and help.
Will follow your advice: "... need to compile the module before you
can use it ... It can be done by putting the module prior to any uses


of it in the same file."

Regards.
Monir

monir

unread,
Apr 10, 2009, 9:07:35 PM4/10/09
to

dpb;

Thank you for explaining why the compiler was complaining!

I haven't done compiling + linking object files for a while (since
upgrading from MS Fortran v5.1 and IBM Fortran v??).
If I opt for putting the module in its own file (as an alternative to
putting it prior to any Use's suggested by Richard and Ron) then I
suppose (with the g95 compiler) I've to either go with the default or
specify *.mod (not *.obj) in creating the object file for the modules
file, otherwise the compiler would complain again for not finding
*.mod.

Ron Shepard has just replied and kindly provided a very detailed
revised and tested version of my 1st (primitive!) F90 attempt. It
would take me some time to digest his code, and thus I probably
wouldn't face the compilation/linking issue for a while anyway.

Kind regards.
Monir

monir

unread,
Apr 10, 2009, 9:11:16 PM4/10/09
to
On Apr 10, 6:29 pm, Ron Shepard <ron-shep...@NOSPAM.comcast.net>
wrote:
> In article
> <848eb928-6c9b-40ab-abed-6ed340852...@q16g2000yqg.googlegroups.com>,

Ron;

Thank you once again for taking the time, not only to explain each
step but also to revise my *primitive* 1st attempt in F90 (and even to
compile it). Very kind and generous of you!

I'll first try to understand *some* of the features in your F90 code,
rather than treating it as a black box and go ahead with the
compilation (complete with the data). This will help me in the long
run.

Your tremendous help is greatly appreciated.
Monir

monir

unread,
Apr 13, 2009, 9:09:38 PM4/13/09
to
> Monir- Hide quoted text -
>
> - Show quoted text -

Hi;

1) One of the (many!!) difficulties I'm faced with in replacing the
F77 Common blocks with the F90 Modules is when (as often the case) the
same common block has different variable names (same type and same
order) in different program units.
For example:
Subroutine One
Common Block /XYCRT/ Xcrt(30), Ycrt(30), n
..........................
Subroutine Two
Common Block /XYCRT/ Xa(30), Ya(30), m
......................
2) Do I need to create 2 modules and allocate each variable in the two
lists ?? or
create just 1 module (makes more sense), allocate its set of
variables, and USE the same module in the second subroutine with some
kind of equivalence to point to the 2nd variable list ??

3) For the above subroutines One and Two, I tried:

Module maxDIMEN
integer :: maxDIM ! 30
End Module maxDIMEN

Module XYCRT
integer :: n
End Module XYCRT
......................
......................
maxDIM = ...
Call Allocate_stuff
......................
......................
Subroutine Allocate_Stuff
use maxDIMEN
use XYCRT
Allocate( Xcrt(maxDIM), Ycrt(maxDIM) )
......................
Return
End
......................
Subroutine One
use maxDIMEN
use XYCRT
......................
Return
End
......................
Subroutine Two
use maxDIMEN
use ! what for Xa() and Ya() ??
......................
Return
End

Your help would be greatly appreciated.
Monir

Ron Shepard

unread,
Apr 14, 2009, 1:16:08 AM4/14/09
to
In article
<50c8ee82-f653-4220...@b16g2000yqb.googlegroups.com>,
monir <mon...@mondenet.com> wrote:

> Subroutine One
> Common Block /XYCRT/ Xcrt(30), Ycrt(30), n
> ..........................
> Subroutine Two
> Common Block /XYCRT/ Xa(30), Ya(30), m

I would recommend fixing this before converting it to a module. This
was in that list of steps in my previous post. This means that you
have to modify the variable names in the subroutines that use one of
these lists so that they agree with those that use the other list.

If, for some reason, that is too difficult to do, then an
alternative is to create the module with one set of variables, and
then change the names in the rename list when using that module in
the other set of subroutines. It would end up looking something like

use xycrt_mod Xa=>Xcrt, Ya=>Ycrt, m=>n

Those look sort of like pointer assignments, but they aren't, they
rename the module variable names. When you do this, the original
module names cannot be used to access those variables. In fact,
those names can then be used for other variables, which is one
reason for doing the renames, but I don't recommend doing that (on
purpose) because it gets really confusing trying to track down what
a variable really is.

$.02 -Ron Shepard

monir

unread,
Apr 14, 2009, 3:40:30 PM4/14/09
to
On Apr 14, 1:16 am, Ron Shepard <ron-shep...@NOSPAM.comcast.net>
wrote:
> In article
> <50c8ee82-f653-4220-a362-425fc5b07...@b16g2000yqb.googlegroups.com>,

Ron;

Thank you for your patience!!
1) You're correct! Step 2 of your earlier reply reads:
"2. Make sure that all declarations of each common block use the same
variable list (in the same order)"
I concentrated at the time on "in the same order". Now I understand
what you meant.

2) As per your recommendation, I've modified the variable names in the
lists of all subprograms that use same common blocks. As you advised,
this is by far more manageable and less confusing than the alternative
of creating a module with one set of variables and renaming the other
lists of the other subprograms when using that module. It would be
extremely difficult (if not imposible) to track down the changes in
the variable names at a given point.

3) Now I'm getting a g95 compiler error:
cpyzero(2,1) = ZBRENT(DCPVAL,theta(i,j+1,k), theta(i,j+1,k+1),tol)
*Error: Type/rank of actual function at (DCPVAL) does not match the
dummy function*

with ref to the 1st arg (i.e.; DCPVAL) in the 1st use of ZBRENT, as
indicated in the relevant listing Item 5) below.
ZBRENT and DCPVAL are external functions.
I've searched this DG and other groups for the correct interpretation
of the above error message with no avail.

Please advise if the cause of the error is obvious to you.
Otherwise, please don't spend any more time on this, unless you find
going back to F90 *basics* is somehow refreshing:)
I've already consumed too much of your time (and Usenet space!) and
it's a bit embarrassing to deprive other users from your expertise.
Will get it working one day!

Kind regards.
Monir

4) Here's what works (F77, g95):
c*********************************************
SUBROUTINE DCpZeros
c*********************************************
Dimension xcrt(30),ycrt(30) !!largest of nRdim, nTHdim
real cpyzero(2,2),cpzzero(2,2), crossing(2,3)
Common /CRT/xcrt,ycrt,n
c.......
EXTERNAL DCPVAL
c.......
DO 51 m=1,nthdim
xcrt(m) = theta(i,j+1,m)
ycrt(m) = dcpbyr(i,j+1,m)
51 Continue
n = nthdim

cpyzero(2,1) = ZBRENT(DCPVAL,theta(i,j+1,k),theta(i,j+1,k
+1),tol)
c......
Return
End

c *************************************
FUNCTION ZBRENT(func, x1, x2, tol)
c *************************************
c no declarations
c........myCode .....
ZBRENT = b
Return
End

c ****************************
FUNCTION dcpval(X)
c ****************************
real x, y, Y2A(30), d1, dn
integer n
real Xcrt(30),Ycrt(30)
Common /CRT/ Xcrt,Ycrt,n
c.......
dcpval = y
Return
End

<>=============================================<>
5) Latest relevant bits of F90 code which produce the compiler error:

Module DIM
integer ::nPlanes,nRdim,nTHdim
End Module DIM

Module maxDIMEN
integer :: maxDIM ! 30
End Module maxDIMEN

Module CRT
integer :: n
real, allocatable :: Xcrt(:),Ycrt(:)
End Module CRT

Subroutine ReadInp()
use DIM
use maxDIMEN
......................
nPlanes = ...! computed
nRdim = ...
nTHdim = ...
maxDIM = ...
Call Allocate_stuff()
......................
End Subroutine ReadInp

Subroutine Allocate_Stuff()
use DIM
use maxDIMEN
use CRT
......................


Allocate( Xcrt(maxDIM), Ycrt(maxDIM) )
......................
Return

End Subroutine Allocate_Stuff

Subroutine DCpZeros()
use DIM
use maxDIMEN
use CRT
real :: cpyzero(2,2),cpzzero(2,2)
real :: crossing(2,3),denominator
EXTERNAL DCPVAL
......................
DO 51 m=1,nTHdim
xcrt(m) = theta(i,j+1,m)
ycrt(m) = dcpbyr(i,j+1,m)
51 Continue
n = nTHdim
cpyzero(2,1) = ZBRENT(DCPVAL,theta(i,j+1,k),theta(i,j+1,k
+1),tol) ! compiler error
......................
DO 302 m=1,nRdim
xcrt(m) = rbys(i,m,k+1)
ycrt(m) = dcpbyth(i,m,k+1)
302 Continue
n = nRdim
cpzzero(1,2) = ZBRENT(DCPVAL,rbys(i,j,k+1),rbys(i,j+1,k+1),tol)
!..many more similar loops for assigning xcrt,ycrt,n
!..Should I call Allocate_Stuff() before each use of ZBRENT to
update ??
!..The constant variable "n" should be allocated some where ?
!..Maybe I should:
!...remove Use CRT from sub Allocate_Stuff() and its allocate
statement;
!...create a new sub Allocate_VarCRT() for CRT; and
!...call the new sub before each ZBRENT.
!...It makes sense. But is it the correct approach ??
!..Ref. doesn't say much. Very confusing!
Return
End

!**********************************
FUNCTION ZBRENT(func, x1, x2, tol)
!**********************************
! no declarations
!........myCode .....
ZBRENT = b
Return
End Function Zbrent

! ****************************
FUNCTION dcpval(X)
! ****************************
use maxDIMEN
use CRT
use Y2AA
real :: x, y, d1, dn

!--Calculate the first derivative of the function at the first and
last point of the range Xcrt.
CALL DERIVPOL(Xcrt, Ycrt, 3, Xcrt(1), d1)
!........................
dcpval = y
Return
End Function dcpval

glen herrmannsfeldt

unread,
Apr 14, 2009, 4:16:22 PM4/14/09
to
monir <mon...@mondenet.com> wrote:
(snip)


> 3) Now I'm getting a g95 compiler error:
> cpyzero(2,1) = ZBRENT(DCPVAL,theta(i,j+1,k), theta(i,j+1,k+1),tol)
> *Error: Type/rank of actual function at (DCPVAL) does not match the
> dummy function*

(snip)

> c *************************************
> FUNCTION ZBRENT(func, x1, x2, tol)
> c *************************************
> c no declarations
> c........myCode .....
> ZBRENT = b
> Return
> End

Here I see no declaration for func, and it is not even
referenced in an expression such that the compiler knows
that it is a function.

Fortran 66 and Fortran 77 style, dummy argument functions
were recognized as being used in expressions with an
argument list in parentheses but not declared as an array.

It is detecting some type of mismatch between func and
DCPVAL (the actual argument function).

-- glen

monir

unread,
Apr 14, 2009, 9:51:09 PM4/14/09
to

Glen;

Actually I've function func referenced in the Function ZBRENT:


c *************************************
FUNCTION ZBRENT(func, x1, x2, tol)
c *************************************
c no declarations

c........myCode21.....
fa = func(a)
fb = func(b)
c........myCode22.....


ZBRENT = b
Return
End

As I indicated in my previous post (Apr 14, 3:40 pm, Item 4), the F77
code works fine with no declarations.
Maybe F90 requires func to be declared as external in Fun ZBRENT.
Will try it first thing in the morning.

Thank you.
Monir

glen herrmannsfeldt

unread,
Apr 14, 2009, 11:57:07 PM4/14/09
to
monir <mon...@mondenet.com> wrote:

> On Apr 14, 4:16?pm, glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
>> monir <mon...@mondenet.com> wrote:

>> (snip)

>> > 3) Now I'm getting a g95 compiler error:

>> > ? ?cpyzero(2,1) = ZBRENT(DCPVAL,theta(i,j+1,k), theta(i,j+1,k+1),tol)


>> > *Error: Type/rank of actual function at (DCPVAL) does not match the
>> > dummy function*

>> (snip)

>> > c *************************************
>> > ? ? ?FUNCTION ZBRENT(func, x1, x2, tol)


>> > c *************************************
>> > c no declarations
>> > c........myCode .....

>> > ? ? ?ZBRENT = b
>> > ? ? ?Return
>> > ? ? ?End

>> Here I see no declaration for func, and it is not even
>> referenced in an expression such that the compiler knows

>> that it is a function. ?

>> Fortran 66 and Fortran 77 style, dummy argument functions
>> were recognized as being used in expressions with an
>> argument list in parentheses but not declared as an array.

>> It is detecting some type of mismatch between func and
>> DCPVAL (the actual argument function).

> Actually I've function func referenced in the Function ZBRENT:
> c *************************************
> FUNCTION ZBRENT(func, x1, x2, tol)
> c *************************************
> c no declarations
> c........myCode21.....
> fa = func(a)
> fb = func(b)
> c........myCode22.....
> ZBRENT = b
> Return
> End

> As I indicated in my previous post (Apr 14, 3:40 pm, Item 4), the F77
> code works fine with no declarations.

Yes, no declarations is fine. But the arguments have to agree,
and DCPVAL has more than one argument.

> Maybe F90 requires func to be declared as external in Fun ZBRENT.
> Will try it first thing in the morning.

I don't believe it is required, though most people do
to make it less confusing (to the reader).

-- glen

monir

unread,
Apr 15, 2009, 12:29:05 PM4/15/09
to
On Apr 14, 11:57 pm, glen herrmannsfeldt <g...@ugcs.caltech.edu>
> -- glen- Hide quoted text -

>
> - Show quoted text -

Glen;

Thank you for your reply.
1) Declaring func as external in ZBRENT didn't solve the problem!

2) >"Yes, no declarations is fine. But the arguments have to agree,


>and DCPVAL has more than one argument."

Function DCPVAL has ONLY one argument as posted earlier:

! ****************************
FUNCTION dcpval(X)
! ****************************
use maxDIMEN
use CRT
use Y2AA
real :: x, y, d1, dn

!........................


CALL DERIVPOL(Xcrt, Ycrt, 3, Xcrt(1), d1)
!........................
dcpval = y
Return
End Function dcpval

3) The compiler error:


cpyzero(2,1) = ZBRENT(DCPVAL,theta(i,j+1,k), theta(i,j+1,k
+1),tol)

"Error: Type/rank of actual function at (DCPVAL) does not match the
dummy function"

is most likely the result of incorrectly allocating the variables of
module CRT and how I use it in Sub DcpZeros, which in turn uses the
Fun ZBRENT.

4) Will systematically modify the code (as per my list following 302
below, one at a time), and hopefully one would work.
!.....


Module CRT
integer :: n
real, allocatable :: Xcrt(:),Ycrt(:)
End Module CRT

!.....


Subroutine DCpZeros()
use DIM
use maxDIMEN
use CRT
real :: cpyzero(2,2),cpzzero(2,2)
real :: crossing(2,3),denominator
EXTERNAL DCPVAL
......................
DO 51 m=1,nTHdim
xcrt(m) = theta(i,j+1,m)
ycrt(m) = dcpbyr(i,j+1,m)
51 Continue
n = nTHdim
cpyzero(2,1) = ZBRENT(DCPVAL,theta(i,j+1,k),theta(i,j+1,k
+1),tol) ! compiler error
......................
DO 302 m=1,nRdim
xcrt(m) = rbys(i,m,k+1)
ycrt(m) = dcpbyth(i,m,k+1)
302 Continue
n = nRdim
cpzzero(1,2) = ZBRENT(DCPVAL,rbys(i,j,k+1),rbys(i,j+1,k+1),tol)

!..many more similar loops for assigning xcrt,ycrt,n
!..Should I call Allocate_Stuff() before each use of ZBRENT to

!..update the variables declared in module CRT and shared by
!..this sub DCpZeros and function DCPVAL ?
!..The constant variable "n" should be allocated somewhere ?


!..Maybe I should:
!...remove Use CRT from sub Allocate_Stuff() and its allocate
statement;
!...create a new sub Allocate_VarCRT() for CRT; and

!...call the new sub before each ZBRENT statement in this sub


!...It makes sense. But is it the correct approach ??

Return
End

Kind regards.
Monir

dpb

unread,
Apr 15, 2009, 12:58:07 PM4/15/09
to
monir wrote:
...

> 3) The compiler error:
> cpyzero(2,1) = ZBRENT(DCPVAL,theta(i,j+1,k), theta(i,j+1,k
> +1),tol)
> "Error: Type/rank of actual function at (DCPVAL) does not match the
> dummy function"
>
> is most likely the result of incorrectly allocating the variables of
> module CRT and how I use it in Sub DcpZeros, which in turn uses the
> Fun ZBRENT.
...

Read the message -- it says the actual function doesn't match in _TYPE_
or _RANK_. That's not arguments to the function not agreeing, it's the
function itself.

I've not tried to follow the actual mishmash of code segments, you tend
to dice stuff up so badly it's extremely difficult to parse w/o a lot of
effort, but I'd recommend reading the error message and acting on its
indication rather than going off on some other tangent.

In general, I'd suspect one or the other is REAL*8 and the other REAL*4
or something similar.

I'd also suggest moving _all_ the code into modules rather than a
mishmash of some with and some without.

If IMPLICIT NONE isn't used religiously, I'd also recommend that to aid
in finding any typos or other misnamed or other unintended variable names.

--

Richard Maine

unread,
Apr 15, 2009, 1:14:05 PM4/15/09
to
monir <mon...@mondenet.com> wrote:
...

> > >> > *Error: Type/rank of actual function at (DCPVAL) does not match the
> > >> > dummy function*

> 1) Declaring func as external in ZBRENT didn't solve the problem!

I suggest rereading the error message. It is griping about the type or
rank. While it is reasonably pausible that other kinds of errors (such
as not being declared external when needed) could confusingly generate
this error message, my first inclination is to at least consider the
possibility that the message might mean exactly what it says; that does
sometimes happen.

So check the type and rank. Check it in *BOTH* places, the caller and
the callee. Rank is easy, as it is a scalar both places (f77 didn't even
have array-valued functions). So check the type in both the caller and
the callee.

When you do so, be sure to look *ONLY* at what the compiler knows in
that particular scope; that bit is important and in fact is the whole
point of issues with "agreement". In the case of passing procedures as
arguments, you have to have agreement between all 3 relevant things -
the actual argument, the dummy argument, and the procedure itself.

The code uses implicit typing, which makes for having many more bugs and
also makes them harder to debug. I recommend against using implicit
typing. But anyway...

In zbrent, func is declared external (after the modification) and is
used as a function. Using an external as a function without having a
type declaration triggers implicit typing, so the compiler thinks this
is a REAL function (unless you have done something to change that; have
I mentioned that implicit typing is messy).

In the code that calls ZBRENT, what does the compiler know about the
actual agument. You have declared it to be external, but that's all. You
have not done anything to specify that it is a function instead of a
subroutine, so the implicit typing doesn't kick in. Looking at the
function ZBRENT itself is *NOT* the question here. The question is what
the compiler knows solely within the calling procedure. I don't see
anything there (admitedly, I might have overlooked it) to say that
ZBRENT is a function as opposed to a subroutine.

That sounds like the types don't agree. A subroutines has no type and
thus is not the same type as a real function.

Allow me to reiterate my recommendation against using implicit typing.
It looks to me as though that is the source of the problem here in that
you don't realize what things triger the implicit typing and what things
don't. Much better than learning the fine points of how implicit typing
works in cases like this is to not use it.

P.S. All of this, at least the above stuff, is also true of f77. This is
*NOT* new to f90. Valid f77 code is also valid f90 code. Just because
your f77 compiler did not bitch about the code, and perhaps ran it as
intended, that most definitely does not mean it was valid f77. It just
means that the compiler did not notice the error and that the error
didn't happen to cause the program to fail with that particular
compiler. That is not the same thing as being valid f77.

Richard Maine

unread,
Apr 15, 2009, 1:20:37 PM4/15/09
to
dpb <no...@non.net> wrote:

> Read the message -- it says the actual function doesn't match in _TYPE_
> or _RANK_.

...


> If IMPLICIT NONE isn't used religiously, I'd also recommend that to aid
> in finding any typos or other misnamed or other unintended variable names.

Dpb,

I find myself regularly amused by how simillar our approaches to some
things are and how much we often notice the same things. :-)

I didn't see this post of yours until right after I submitted mine,
which said much the same. Not at all the first time that has happened,
and there are plenty of other times when I would have said the same
thing, but read a reply of yours and concluded it said what I was about
to.

nm...@cam.ac.uk

unread,
Apr 15, 2009, 2:01:30 PM4/15/09
to
In article <1iy7ltw.f605tn12mfutcN%nos...@see.signature>,
Richard Maine <nos...@see.signature> wrote:

>dpb <no...@non.net> wrote:
>
>> If IMPLICIT NONE isn't used religiously, I'd also recommend that to aid
>> in finding any typos or other misnamed or other unintended variable names.
>
>I find myself regularly amused by how simillar our approaches to some
>things are and how much we often notice the same things. :-)

That makes several of us :-) The remark about IMPLICIT NONE has
reached the status of a mantra - many of us chant it out of reflex,
on the grounds that it is always a step towards Enlightenment.


Regards,
Nick Maclaren.

dpb

unread,
Apr 15, 2009, 2:03:39 PM4/15/09
to
Richard Maine wrote:
> dpb <no...@non.net> wrote:
>
>> Read the message -- it says the actual function doesn't match in _TYPE_
>> or _RANK_.
> ...
>> If IMPLICIT NONE isn't used religiously, I'd also recommend that to aid
>> in finding any typos or other misnamed or other unintended variable names.
>
> Dpb,
>
> I find myself regularly amused by how simillar our approaches to some
> things are and how much we often notice the same things. :-)
>
> I didn't see this post of yours until right after I submitted mine,
> which said much the same. Not at all the first time that has happened,
> and there are plenty of other times when I would have said the same
> thing, but read a reply of yours and concluded it said what I was about
> to.

And I just saw yours... :)

Also as is so often the case, you were willing to delve further into the
bowels of some painful reading and trace down where the actual problem
lay precisely rather than just point out the general area to look. I
had already lost patience in that thread long ago so didn't take long.

It does seem we have similar penchants/hot buttons but your in-depth
knowledge of the Standard and the nuances puts mine to shame
(particularly past F95 where I've basically hibernated) so I often look
at a question and think "Well, I know the superficial answer, but
Richard's bound to be along and will cite chapter and verse so I'll just
wait..." :)

-d(uane)pb(ozarth)

--


glen herrmannsfeldt

unread,
Apr 15, 2009, 2:11:13 PM4/15/09
to
Richard Maine <nos...@see.signature> wrote:
(snip)


> When you do so, be sure to look *ONLY* at what the compiler knows in
> that particular scope; that bit is important and in fact is the whole
> point of issues with "agreement". In the case of passing procedures as
> arguments, you have to have agreement between all 3 relevant things -
> the actual argument, the dummy argument, and the procedure itself.

> The code uses implicit typing, which makes for having many more bugs and
> also makes them harder to debug. I recommend against using implicit
> typing. But anyway...

> In zbrent, func is declared external (after the modification) and is
> used as a function. Using an external as a function without having a
> type declaration triggers implicit typing, so the compiler thinks this
> is a REAL function (unless you have done something to change that; have
> I mentioned that implicit typing is messy).

> In the code that calls ZBRENT, what does the compiler know about the
> actual agument. You have declared it to be external, but that's all. You
> have not done anything to specify that it is a function instead of a
> subroutine, so the implicit typing doesn't kick in. Looking at the
> function ZBRENT itself is *NOT* the question here. The question is what
> the compiler knows solely within the calling procedure. I don't see
> anything there (admitedly, I might have overlooked it) to say that
> ZBRENT is a function as opposed to a subroutine.

Was this one new in Fortran 77? It is somewhat obvious that
the reference to the dummy function and the function itself must
have the same type. It isn't so obvious, especially in Fortran 66,
that the actual argument needs a type, other than to be EXTERNAL.
(That implicit typing wouldn't work.) If it was new in Fortran 77,
it is likely that Fortran 77 compilers would support the older
form, at least on systems (most that I know) where the just the
address of the function or subroutine goes into the call.

-- glen

ken.fa...@gmail.com

unread,
Apr 15, 2009, 5:50:52 PM4/15/09
to
On Apr 15, 10:14 am, nos...@see.signature (Richard Maine) wrote:
> monir <mon...@mondenet.com> wrote:
>
> ...
>
> > > >> > *Error: Type/rank of actual function at (DCPVAL) does not match the
> > > >> > dummy function*
> > 1) Declaring func as external in ZBRENT didn't solve the problem!

[...]


>
> In zbrent, func is declared external (after the modification) and is
> used as a function. Using an external as a function without having a
> type declaration triggers implicit typing, so the compiler thinks this
> is a REAL function (unless you have done something to change that; have
> I mentioned that implicit typing is messy).
>
> In the code that calls ZBRENT, what does the compiler know about the
> actual agument. You have declared it to be external, but that's all. You
> have not done anything to specify that it is a function instead of a
> subroutine, so the implicit typing doesn't kick in. Looking at the
> function ZBRENT itself is *NOT* the question here. The question is what
> the compiler knows solely within the calling procedure. I don't see
> anything there (admitedly, I might have overlooked it) to say that
> ZBRENT is a function as opposed to a subroutine.

^^^^^^

Just to clarify for monir...it is DCPVAL which is
declared EXTERNAL but not given a type in the caller.
DCPVAL in the caller corresponds to func in ZBRENT,
and it is DCPVAL that needs to be declared (presumably
REAL) in the caller.

I know Richard (and dpb and Nick) knows this, but
I suspect that monir might not appreciate the typo
and simply try to declare ZBRENT in the caller to
no avail. :-(

[...]

Regards, Ken

Richard Maine

unread,
Apr 15, 2009, 6:33:21 PM4/15/09
to
<ken.fa...@gmail.com> wrote:

Oops. Yeah. Thanks for the correction.

Jugoslav Dujic

unread,
Apr 16, 2009, 4:08:04 AM4/16/09
to

> -d(uane)pb(ozarth)

Damn, and I was wondering who is that clever but mysterious dpb...
I didn't connect the dots I admit. Checking back Google archives,
you have nearly always signed as "dpb", but at one point
you ceased to use the full name, possibly after the break
in your posts (cca. 2003-2006). Well... um... hello :D.

--
Jugoslav
www.xeffort.com
Please reply to the newsgroup.
You can find my real e-mail on my home page above.

dpb

unread,
Apr 16, 2009, 1:25:54 PM4/16/09
to
Jugoslav Dujic wrote:
>
>> -d(uane)pb(ozarth)
>
> Damn, and I was wondering who is that clever but mysterious dpb...
> I didn't connect the dots I admit. Checking back Google archives,
> you have nearly always signed as "dpb", but at one point
> you ceased to use the full name, possibly after the break
> in your posts (cca. 2003-2006). Well... um... hello :D.
...
Uuuhhhh, hello back... :)

I had thought I had made that connection with you previously during some
of our offline communications. Sorry it didn't seem to connect, it
really isn't something I did/do for anything but because of some
(non-clf-related) issues that arose and just let it stay when those went
away...

Every so often I throw the name in again when it seems appropriate.
Comments from Richard of that ilk seemed appropriate, indeed... :)

--

monir

unread,
Apr 16, 2009, 2:22:06 PM4/16/09
to
1) Richard wrote:
> In the code that calls ZBRENT, what does the compiler know about the
> actual argument. You have declared it to be external, but that's all. You

> have not done anything to specify that it is a function instead of a
> subroutine, so the implicit typing doesn't kick in. Looking at the
> function ZBRENT itself is *NOT* the question here. The question is what
> the compiler knows solely within the calling procedure. I don't see
> anything there (admittedly, I might have overlooked it) to say that

> ZBRENT is a function as opposed to a subroutine.

Based on my little knowledge of Fortran, External identifies the name
as subroutine OR function. Correct ??
I don't know how to tell the compiler DCPVAL is a fun and not a sub.
I thought how the name is referenced in the code tells the compiler.
Apparently this no longer the case and one has to specify which
external procedure is a sub and which is a fun. But how ?
(I thought also that most compilers assume undefined names (typos for
example) in a program unit to be defined externally, and display the
error message "external ref. not defined" or something to that
effect.)

2) Richard wrote:
>Just because your f77 compiler did not bitch about the code, and
>perhaps ran it as intended, that most definitely does not mean it
>was valid f77. It just means that the compiler did not notice the error
>and that the error didn't happen to cause the program to fail with
>that particular compiler. That is not the same thing as being valid f77.

OK. My F77 program in question (a research tool, which I'm trying to
upgrade some aspects of it to F90 using the dynamic arrays feature you
and others have recommended earlier) compiles successfully (earlier
with MS Fortran v5.1 then with IBM Fortran, and recently with g95).
The F77 program runs as desired producing the correct results for all
the input scenarios I've tested for the last few years.
I'm not claiming it to be either elegant or efficient by your
standard, or even bug-free, but it works perfectly as intended and on
different m/cs.
What else should I be concerned with to designate it as *reliable* and
*valid f77* ??

3) Ken wrote:
>Just to clarify for monir...it is DCPVAL which is
>declared EXTERNAL but not given a type in the caller.
>DCPVAL in the caller corresponds to func in ZBRENT,
>and it is DCPVAL that needs to be declared (presumably
>REAL) in the caller.

I take it to mean in sub DCpZeros. Correct ?? Isn't that implicit ?
Anyway just to make sure I interpreted your suggestion correctly, I
declared the name of the External as real throughout, one declaration
at a time.

4) First:
Declared DCPVAL as real in Sub DCpZeros. Same g95 compiler error
message:


cpyzero(2,1) = ZBRENT(DCPVAL,theta(i,j+1,k), theta(i,j+1,k
+1),tol)

*Error: Type/rank of actual function at (DCPVAL) does not match the
dummy function*

with ref to the 1st arg (i.e.; DCPVAL) in the 1st use of ZBRENT.

5) Second:
Declared also func as real in Fun ZBRENT.
The above compiler error DISAPPEARED!!!!
A bit surprising, since according to Richard and others: "Valid F77
code is also valid F90 code."

In any event, now I'm getting:
C:\...\EULER-2D-mesh3-F90>g95 -o PRSCAV8d-F90-c PRSCAV8d-F90-c.for
C:\...\LOCALS~1\Temp/cce8baaa.o:PRSCAV8d-F90-c.for:(.text+0x8239):
undefined reference to `dcpval_'
C:\...\LOCALS~1\Temp/cce8baaa.o:PRSCAV8d-F90-c.for:(.text+0x8431):
more undefined references to `dcpval_' follow

Perhaps I should re-visit Richard's suggestion (Item 1 above).
Does the above refer somehow to where "dcpval" is undefined ??
Are +0x8239, +0x8431, etc. references to the list file ??

6) Here's the latest attempt (F90):

c *************************************
Subroutine DCpZeros()
c *************************************
use DIM
use ABSCISAE
use VVALUES
use DCP
use LST2
use PARM


use maxDIMEN
use CRT
......................

External DCPVAL
real DCPVAL
......................
cpyzero(2,1) = ZBRENT(DCPVAL,theta(i,j+1,k),theta(i,j+1,k+1),tol)
......................
Return
End Subroutine DCpZeros

c *************************************
FUNCTION ZBRENT(func, x1, x2, tol)
c *************************************

External func
real func


........myCode21.....
fa = func(a)
fb = func(b)

........myCode22.....
ZBRENT = b
Return

End Function Zbrent

! ****************************
real FUNCTION dcpval(X)


! ****************************
use maxDIMEN
use CRT
use Y2AA
real :: x, y, d1, dn

........................
CALL DERIVPOL(Xcrt, Ycrt, 3, Xcrt(1), d1)

........................
dcpval = y
Return
End Function dcpval


Kind regards.
Monir

Richard Maine

unread,
Apr 16, 2009, 3:00:47 PM4/16/09
to
monir <mon...@mondenet.com> wrote:

> Based on my little knowledge of Fortran, External identifies the name
> as subroutine OR function. Correct ??

Yes.

> I don't know how to tell the compiler DCPVAL is a fun and not a sub.

By giving it a type. Subroutines don't have a type; functions do. Recall
that type is what the compiler was bitching about. See my comments about
implicit. Give it a type explicitly and you won't get caught up in that
mess. (Or you can go further and give it an explicit interface, but I'd
recommend - as others have in this thread - that you go to module
procedures before you do that.)

> I thought how the name is referenced in the code tells the compiler.
> Apparently this no longer the case and one has to specify which
> external procedure is a sub and which is a fun. But how ?

See above. Also see my prior comments about looking *ONLY* in the
scoping unit in question. That really is incredibly important. *ALWAYS*
keep it in mind when dealing with procedures. If you don't, you will
just make one error after another. Now look in the routine that calls
ZBRENT (I forget its name). How is DCPVAL referenced there in a way that
would tell the compiler it is a function? Unless I missed it, it isn't.
The only mentions of DCPVAL in that scope are the EXTERNAL statement
(when added) and its presence in an actual argument list. Neither of
these say anything about being a function versus subroutine.

> (I thought also that most compilers assume undefined names (typos for
> example) in a program unit to be defined externally, and display the
> error message "external ref. not defined" or something to that
> effect.)

Well, that's a severe overstatement, as most undefined names won't look
like externals at all. Counting on the compiler to catch things like
typos just doesn't even come close to working unless you use implicit
none, which you don't (see prior messages). It is also not the compiler,
but the linker that gives you messages about undefined externals, and
that happens only in cases where the compiler has identified (correctly
or not) the name as an external.

>
> 2) Richard wrote:
> >Just because your f77 compiler did not bitch about the code, and
> >perhaps ran it as intended, that most definitely does not mean it
> >was valid f77. It just means that the compiler did not notice the error
> >and that the error didn't happen to cause the program to fail with
> >that particular compiler. That is not the same thing as being valid f77.
>

> What else should I be concerned with to designate it as *reliable* and
> *valid f77* ??

Conforming to the standard.

> A bit surprising, since according to Richard and others: "Valid F77
> code is also valid F90 code."

You haven't demonstrated that you had valid f77 code. See above.


>
> In any event, now I'm getting:

...


> more undefined references to `dcpval_' follow

That looks unrelated. My first suspicion would be that the file with the
code for dcpval didn't actually get linked in at all, but I don't have
the information to tell.

dpb

unread,
Apr 16, 2009, 4:02:25 PM4/16/09
to
Richard Maine wrote:
...

> See above. Also see my prior comments about looking *ONLY* in the
> scoping unit in question. That really is incredibly important. *ALWAYS*
> keep it in mind when dealing with procedures. If you don't, you will
> just make one error after another. ...

And to double reinforce the point --

A "scoping unit" is the specific main program, subroutine or function in
question and _ONLY_ that particular program or subprogram.

Whether multiple functions or subroutines are included in the same file
submitted to the compiler at the same time or not is
_absolutely_immaterial_.

--


glen herrmannsfeldt

unread,
Apr 16, 2009, 4:49:50 PM4/16/09
to
monir <mon...@mondenet.com> wrote:
> 1) Richard wrote:
>> In the code that calls ZBRENT, what does the compiler know about the
>> actual argument. You have declared it to be external, but that's all. You
>> have not done anything to specify that it is a function instead of a
>> subroutine, so the implicit typing doesn't kick in. Looking at the
>> function ZBRENT itself is *NOT* the question here. The question is what
>> the compiler knows solely within the calling procedure. I don't see
>> anything there (admittedly, I might have overlooked it) to say that
>> ZBRENT is a function as opposed to a subroutine.

> Based on my little knowledge of Fortran, External identifies the name
> as subroutine OR function. Correct ??
> I don't know how to tell the compiler DCPVAL is a fun and not a sub.

It seems that you give it a type. Functions have type, subroutines
don't. As far as I know Fortran 66 didn't have this requirement,
and C doesn't either.

> I thought how the name is referenced in the code tells the compiler.
> Apparently this no longer the case and one has to specify which
> external procedure is a sub and which is a fun. But how ?

> (I thought also that most compilers assume undefined names (typos for
> example) in a program unit to be defined externally, and display the
> error message "external ref. not defined" or something to that
> effect.)

That message usually comes at link time. Undimensioned array
references, except as l-values, look like functions references.
Variables don't look like functions, so the compiler doesn't
need to consider them external.



> 2) Richard wrote:
>>Just because your f77 compiler did not bitch about the code, and
>>perhaps ran it as intended, that most definitely does not mean it
>>was valid f77. It just means that the compiler did not notice the error
>>and that the error didn't happen to cause the program to fail with
>>that particular compiler. That is not the same thing as being valid f77.

(snip)



> 3) Ken wrote:
>>Just to clarify for monir...it is DCPVAL which is
>>declared EXTERNAL but not given a type in the caller.
>>DCPVAL in the caller corresponds to func in ZBRENT,
>>and it is DCPVAL that needs to be declared (presumably
>>REAL) in the caller.

> I take it to mean in sub DCpZeros. Correct ?? Isn't that implicit ?
> Anyway just to make sure I interpreted your suggestion correctly, I
> declared the name of the External as real throughout, one declaration
> at a time.

(snip)


> 5) Second:
> Declared also func as real in Fun ZBRENT.
> The above compiler error DISAPPEARED!!!!
> A bit surprising, since according to Richard and others: "Valid F77
> code is also valid F90 code."

I haven't looked at the F77 standard to see if I agree or not.



> In any event, now I'm getting:
> C:\...\EULER-2D-mesh3-F90>g95 -o PRSCAV8d-F90-c PRSCAV8d-F90-c.for
> C:\...\LOCALS~1\Temp/cce8baaa.o:PRSCAV8d-F90-c.for:(.text+0x8239):
> undefined reference to `dcpval_'
> C:\...\LOCALS~1\Temp/cce8baaa.o:PRSCAV8d-F90-c.for:(.text+0x8431):
> more undefined references to `dcpval_' follow

This looks like it is worse than we thought. I wonder
if something on one of the modules could be affecting it?



> Perhaps I should re-visit Richard's suggestion (Item 1 above).
> Does the above refer somehow to where "dcpval" is undefined ??
> Are +0x8239, +0x8431, etc. references to the list file ??

They are offsets into the machine code. Mostly they
don't help you.

-- glen

Richard Maine

unread,
Apr 16, 2009, 5:14:53 PM4/16/09
to
glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

> It seems that you give it a type. Functions have type, subroutines
> don't. As far as I know Fortran 66 didn't have this requirement,
> and C doesn't either.

I'm not interested in delving into the f66 aspects of this. I took a
quick glance and thought that what I saw was internaly inconsistent in
the standard, but I didn't (and still don't) feel motivated to study
carefully enough to be sure. For example, the f66 requires type
agreement of arguments and says that the *ONLY* exception is... now I
forget what, but not this. It also talks about the only contexts in
which a procedure name can appear if it is not known to be a subrutine
or a function; looks to me like dummy argument ought to have been one of
those contexts, but I don't see it.

It is hard enough trying to help the OP without delving into that
particular arcania. In fact, the whole issue of having procedures
without establishing them as being subroutines or functions counts as
arcania in my view. I admit as to getting confused myself as to exactly
when it is and isn't allowed and in what versions of the standard. I
find it confusing enough that I could also well believe that some
compilers could get it wrong. I'll stop with "the compiler was bitching
about the type, so fix the type" along with "making the type explicit is
a better way to code this anyway (module procedures are an even better
way) so just do it instead of worrying about whether or not you ought to
have been able to get by without it."

The comment makes no sense for C. C doesn't have subroutines at all. The
closest equivalent is a function with a void return. I can't translate
your statement above into anything that I can make sense of in a C
context. It isn't a question of whether the requirement exists or not, I
can't even translate what a corresponding requirement would be.

glen herrmannsfeldt

unread,
Apr 16, 2009, 6:07:41 PM4/16/09
to
Richard Maine <nos...@see.signature> wrote:
(big snip related to function names as actual arguments)


> The comment makes no sense for C. C doesn't have subroutines at all. The
> closest equivalent is a function with a void return. I can't translate
> your statement above into anything that I can make sense of in a C
> context. It isn't a question of whether the requirement exists or not, I
> can't even translate what a corresponding requirement would be.

As you say, I like to consider the implementation. The calling
sequence of the actual call to the function, and the function itself
must be consistent. In the usual implementation, the actual argument
supplies the address of the function (or subroutine). It does that
independent of the name being a function or subroutine.

C has (void*) pointers which can point to any data type,
and ((void*)()) pointers which can point to any function type.
(Some systems allow (void*) pointers to point to functions,
but not all do.) The reason for the comment is that,
assuming void functions correspond to subroutines, an implementation
consistent with C doesn't distinguish function and subroutine
in the actual argument.

I am not sure which version of Fortran changed that.

-- glen

monir

unread,
Apr 17, 2009, 12:21:13 PM4/17/09
to
On Apr 16, 5:14 pm, nos...@see.signature (Richard Maine) wrote:
> glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
> > It seems that you give it a type.  Functions have type, subroutines
> > don't.  As far as I know Fortran 66 didn't have this requirement,
> > and C doesn't either.

Thank you all once again for sharing your in-depth knowledge on the
subject matter.

>>C:\...\LOCALS~1\Temp/cce8baaa.o:PRSCAV8d-F90-c.for:(.text+0x8239):
>>undefined reference to `dcpval_'

1) Richard wrote;


>That looks unrelated. My first suspicion would be that the file with the
>code for dcpval didn't actually get linked in at all, but I don't have
>the information to tell.

Just for clarification, the entire program (~ 3,000 lines of code) is
in one file, and its code for ALL the subroutines and functions (incl.
the code for dcpval) is contained in one module Used by the main
program.

2) dpb wrote:
>I'd recommend reading the error message and acting on its
>indication rather than going off on some other tangent.

>I'd also suggest moving _all_ the code into modules rather than a
>mishmash of some with and some without.

The statement (at the top of this post) doesn't really say much.
Module CRT is shared ONLY by Sub DCpZeros() and Fun dcpval(), and
that's where (I think) the problem lies, but I could be wrong.
As far as *moving _all_ the code into modules* is concerned, this
might be a risky proposition for someone who is new to the F90 dynamic
arrays and array operations concepts and would certainly drown me at
this point!
Will try it later as a comprehensive exercise once I get the current
F90 program working.

3) Glen wrote:
>This looks like it is worse than we thought. I wonder
>if something on one of the modules could be affecting it?

I suspect this is most likely the case, simply because the modules are
the only major changes I've made to the working F77 program (apart
from declaring the type of all External Functions as real throughout).
Will continue my current *hit-and-miss* approach with particular
emphasis on the modules declarations and Use.

Regards.
Monir

Richard Maine

unread,
Apr 17, 2009, 12:52:54 PM4/17/09
to
monir <mon...@mondenet.com> wrote:

> >>C:\...\LOCALS~1\Temp/cce8baaa.o:PRSCAV8d-F90-c.for:(.text+0x8239):
> >>undefined reference to `dcpval_'
>
> 1) Richard wrote;
> >That looks unrelated. My first suspicion would be that the file with the
> >code for dcpval didn't actually get linked in at all, but I don't have
> >the information to tell.

...


> 2) dpb wrote:
> >I'd also suggest moving _all_ the code into modules rather than a
> >mishmash of some with and some without.

...


> the modules are
> the only major changes I've made to the working F77 program (apart
> from declaring the type of all External Functions as real throughout).

Ah. I wasn't thinking much about module issues when I made the above
comment. One easy way to get an error like the above is to try to call a
module procedure without USEing the module. If you don't USE the module,
the compiler won't know it is a module procedure, so it will look for an
external procedure of that name, which doesn't exist.

monir

unread,
Apr 20, 2009, 3:42:38 PM4/20/09
to
On Apr 17, 12:52 pm, nos...@see.signature (Richard Maine) wrote:
> monir <mon...@mondenet.com> wrote:
> > >>C:\...\LOCALS~1\Temp/cce8baaa.o:PRSCAV8d-F90-c.for:(.text+0x8239):
> > >>undefined reference to `dcpval_'
>
> > 1) Richard wrote;
> > >That looks unrelated. My first suspicion would be that the file with the
> > >code for dcpval didn't actually get linked in at all, but I don't have
> > >the information to tell.
> ...
>
> Ah. I wasn't thinking much about module issues when I made the above
> comment. One easy way to get an error like the above is to try to call a
> module procedure without USEing the module. If you don't USE the module,
> the compiler won't know it is a module procedure, so it will look for an
> external procedure of that name, which doesn't exist.
>
> --
> Richard Maine                    | Good judgment comes from experience;
> email: last name at domain . net | experience comes from bad judgment.
> domain: summertriangle           |  -- Mark Twain- Hide quoted text -

>
> - Show quoted text -

Still struggling with the compiler (or linker) complaint.

1) Compiled & Linked with g95:
C:\...\EULER-2D-mesh3-F90>g95 -o PRSCAV8d-F90-e PRSCAV8d-F90-e.for
resulted in 5 displayed statements each with different (.text+????)
term:
C:\...\LOCALS~1\Temp/ccG2baaa.o:PRSCAV8d-F90-e.for:(.text+0x79d7):
undefined reference to `dcpval_'
and 1 statement:
C:\...\LOCALS~1\Temp/ccG2baaa.o:PRSCAV8d-F90-e.for:(.text+0x83bb):


more undefined references to `dcpval_' follow

The above statements MUST be saying more than just "undefined
reference" somewhere in the program !!

2) 'dcpval' function name is only referenced in Sub DCpZeros in the
ZBRENT expressions.
No where else in the program does the name of the function DCpval
appear (except of course in the function itself).

3) notice the underscore displayed at the end of 'dcpval_' (perhaps it
reveals something to the experts.)

4) In Sub DCpZeros: if I comment out ALL the statements that use
Function ZBRENT, the same statements in 1) above are displayed.

5) However, if in addition I comment out the declaration External
DCpval as well, the program compiles successfully and the executable
file is generated (but of course unusable because of 4 above)
This suggests that a name declared as External in a subprogram but not
referenced in that subprogram triggers also the linker statements of
1) above. Clearly, this is NOT the case here (or is it ??)

6) Could it be that there's a special F90 programming provision when a
program unit contains both USE and EXTERNAL ??
(I've even tried placing the attribute declaration External before USE
in DCpZeros)

7) Below is the latest (unsuccessful) attempt which produces 1) above.

Your suggestion(s) would be greatly appreciated.
Monir

c *************************************


Subroutine DCpZeros()
c *************************************
use DIM
use ABSCISAE
use VVALUES
use DCP
use LST2
use PARM
use maxDIMEN
use CRT

implicit none
......................
External Dcpval
real Dcpval
......................
call Allocate_VarCRT()
cpyzero(2,1) = ZBRENT(DCpval,theta(i,j+1,k),theta(i,j+1,k+1),tol)
......................
call Allocate_VarCRT()
cpyzero(1,2) = ZBRENT(DCpval,rbys(i,j,k+1),rbys(i,j+1,k+1),tol)


......................
Return
End Subroutine DCpZeros

! *************************************
real FUNCTION ZBRENT(func, x1, x2, tol)
! *************************************
implicit none
External func
real func


......myCode21.....
fa = func(a)
fb = func(b)

.......myCode22.....
ZBRENT = b
End Function Zbrent

! ****************************
real FUNCTION DCpval(X)


! ****************************
use maxDIMEN
use CRT
use Y2AA

implicit none


real :: x, y, d1, dn
....................

CALL SPLINT(Xcrt, Ycrt, Y2A, n, x, y)
....................
DCpval = y
End Function Dcpval

glen herrmannsfeldt

unread,
Apr 20, 2009, 4:04:53 PM4/20/09
to
monir <mon...@mondenet.com> wrote:
(snip, Richard wrote)

>> Ah. I wasn't thinking much about module issues when I made the above
>> comment. One easy way to get an error like the above is to try to call a
>> module procedure without USEing the module. If you don't USE the module,
>> the compiler won't know it is a module procedure, so it will look for an
>> external procedure of that name, which doesn't exist.

> Still struggling with the compiler (or linker) complaint.

(snip)



> C:\...\LOCALS~1\Temp/ccG2baaa.o:PRSCAV8d-F90-e.for:(.text+0x79d7):
> undefined reference to `dcpval_'

(snip)



> 2) 'dcpval' function name is only referenced in Sub DCpZeros in the
> ZBRENT expressions.

You mentioned modules, but from the posted code it does not look
like dcpval in in a module.

> No where else in the program does the name of the function DCpval
> appear (except of course in the function itself).

> 3) notice the underscore displayed at the end of 'dcpval_' (perhaps it
> reveals something to the experts.)

It is an old unix convention that hasn't gone away.
It doesn't mean anything at all.



> 4) In Sub DCpZeros: if I comment out ALL the statements that use
> Function ZBRENT, the same statements in 1) above are displayed.

> 5) However, if in addition I comment out the declaration External
> DCpval as well, the program compiles successfully and the executable
> file is generated (but of course unusable because of 4 above)
> This suggests that a name declared as External in a subprogram but not
> referenced in that subprogram triggers also the linker statements of
> 1) above. Clearly, this is NOT the case here (or is it ??)

Yes, I believe the EXTERNAL statement is enough to generate
the external reference.


> 6) Could it be that there's a special F90 programming provision when a
> program unit contains both USE and EXTERNAL ??
> (I've even tried placing the attribute declaration External before USE
> in DCpZeros)

There are for module procedures, but it doesn't look like
that is the case here.



> 7) Below is the latest (unsuccessful) attempt which produces 1) above.

(snipped, mostly because without the contents of the USEd
modules I can't do anything with it. Can you make a simpler
example without any USE that demonstarates the error?

-- glen

dpb

unread,
Apr 20, 2009, 4:27:23 PM4/20/09
to
monir wrote:
...

> Still struggling with the compiler (or linker) complaint.
>
> 1) Compiled & Linked with g95:
> C:\...\EULER-2D-mesh3-F90>g95 -o PRSCAV8d-F90-e PRSCAV8d-F90-e.for
> resulted in 5 displayed statements each with different (.text+????)
> term:
> C:\...\LOCALS~1\Temp/ccG2baaa.o:PRSCAV8d-F90-e.for:(.text+0x79d7):
> undefined reference to `dcpval_'
> and 1 statement:
> C:\...\LOCALS~1\Temp/ccG2baaa.o:PRSCAV8d-F90-e.for:(.text+0x83bb):
> more undefined references to `dcpval_' follow
> The above statements MUST be saying more than just "undefined
> reference" somewhere in the program !!
>
> 2) 'dcpval' function name is only referenced in Sub DCpZeros in the
> ZBRENT expressions.

It would be far more useful if you would quit trying to interpret for
the reader and simply supply an unedited sample program and the results
of the compilation/link-step unedited.

This would have two salutatory effects --

a) it would make reading the listing _far_ simpler w/o having to try to
pick out what is/isn't the actual data returned, and

b) it would ensure the full information needed is provided w/o
injudicious selection of what you _think_ might be the problem (but
obviously isn't as if it were, you would have fixed it).

I would suggest (as did Glen) you take a make a toy application of about
three lines -- a main program that calls a routine w/ the passed
function argument but stripped down of the ancillary data and so on to
nothing but the form. It's a good possibility the problem you're facing
will disappear and if so, it will show you what is/isn't being done in
your actual code to mimic the problem.

If, otoh, the problem does still evidence itself, it will be far simpler
for the users of g95 to point you to the problem and the proper fix.
Once that application is working, then you have a model for your
application to add in the necessary parts.

Simplify, simplify, simplify...

Or,

Divide and conquer is also an appropriate mantra.

You're confounding the underlying issue w/ excess complexity and not
helping by not showing sufficient work for anybody else to actually see
the whole picture.

Then, as noted above, you compound that problem w/ excessive
pontificating instead of providing useful data...

--

monir

unread,
Apr 21, 2009, 10:06:43 AM4/21/09
to
On Apr 20, 4:27 pm, dpb <n...@non.net> wrote:

Glen wrote:
1>You mentioned modules, but from the posted code it does not look
,>like dcpval in in a module.
..Function dcpval is NOT in a module.

2> (the underscore in 'dcpval_') is an old unix convention that hasn't
gone away.
,>It doesn't mean anything at all.
..Thanks for the clarification.

3>Yes, I believe the EXTERNAL statement is enough to generate
,>the external reference.
..I also believe so.

4>> 6) Could it be that there's a special F90 programming provision
when a
,>> program unit contains both USE and EXTERNAL ??
,>> (I've even tried placing the attribute declaration External before
USE
,>> in DCpZeros)
,>There are for module procedures, but it doesn't look like
,>that is the case here.
..This exercise is my first encounter with the (F90) module feature.
As such, I'm using the 'simplest' form of modules, basically as
declaration sites made available to any procedure within the program
by the USE statement. I don't believe it can be made any simpler!!

5>> 7) Below is the latest (unsuccessful) attempt which produces 1)
above.
,>(snipped, mostly because without the contents of the USEd
,>modules I can't do anything with it. Can you make a simpler
,>example without any USE that demonstarates the error?
..Will certainly try. *Without any USE* will take me back to the F77
working version of the program (using common blocks).
Will strip the program of all its developer's comments, which
hopefully would bring it down to about 2,000 lines of code, and then
try varying combinations of routines and select (for posting) the
simplest combination that mimics the compilation/linker problem.

dpb wrote:
6>I would suggest (as did Glen) you take a make a toy application of
about
,>three lines -- a main program that calls a routine w/ the passed
,>function argument but stripped down of the ancillary data and so on
to
,>nothing but the form. It's a good possibility the problem you're
facing
,>will disappear and if so, it will show you what is/isn't being done
in
,>your actual code to mimic the problem.
,>If, otoh, the problem does still evidence itself, it will be far
simpler
,>for the users of g95 to point you to the problem and the proper
fix.
,>Once that application is working, then you have a model for your
,>application to add in the necessary parts.
,>Simplify, simplify, simplify...
..Thank you for the your suggestion. Will try it.

Regards.
Monir

dpb

unread,
Apr 21, 2009, 10:41:01 AM4/21/09
to
monir wrote:
> On Apr 20, 4:27 pm, dpb <n...@non.net> wrote:
>
> Glen wrote:
...
> ... Can you make a simpler

> ,>example without any USE that demonstarates the error?
> ..Will certainly try. *Without any USE* will take me back to the F77
> working version of the program (using common blocks).
> Will strip the program of all its developer's comments, which
> hopefully would bring it down to about 2,000 lines of code, and then
> try varying combinations of routines and select (for posting) the
> simplest combination that mimics the compilation/linker problem.

The problem it would seem to be is the _structure_ of what you've placed
where. Far better than random combinations of hit and miss would be to
_study_ the organization of the code and discern what is in which code
section and more importantly, _WHY_ it is placed therein. With that
knowledge and foresight, it should become clear as to what is misplaced
and/or missing.

Clearly from the link messages, there are unsatisfied references to the
routine that aren't able to be resolved by the linker. One obvious
reason for this _MIGHT_ be you're not compiling the module which now
contains that routine whereas before it was included in a different
source file so got compiled transparently. A reason for that could be
as simple as you forgot to add the file in your dependency list in a
makefile.

...

> ..Thank you for the your suggestion. Will try it.

To emphasize -- _LOOK_ at the placement of the code within source files
and modules and extract from that the larger picture of how they are
related instead of looking at the details of the solution of the problem.

Make a toy application that mimics the structure w/o the burden of the
myriad details of getting all the little bits and pieces to make it
solve the problem specifically. It can be as simple as simply returning
2X an input value or something. You can place the dummy function in a
module but keep it simple--the point is to simply duplicate the outline
of the problem to uncover the reason for confusing the linker or why the
piece is missing, _not_ to make a working application at this point.

Once you see the outline of that structure, _THEN_ you can keep the
structure and add in the ancillary complexity. If you break it in a
step, you can then see what broke it and look at why. The "WHY" of what
happens is the important thing here so that you can begin to grasp the
logic behind the process rather than continuing to just try stuff until
something may, essentially by accident, work. The problem with that is
it is very inefficient and even when it does finally succeed (if it ever
does), you don't know what you actually did that caused the error to go
away and so you're always at the mercy of falling back into the same
hole without a ladder with which to climb out again.

And, of course, if after the first step you still duplicate the problem,
_then_ you will have a small enough application you can post the whole
thing for others to dissect with enough context to actually be able to
really help.

--

James Van Buskirk

unread,
Apr 21, 2009, 11:45:30 AM4/21/09
to
"dpb" <no...@non.net> wrote in message news:gskm2k$iod$1...@aioe.org...

> Clearly from the link messages, there are unsatisfied references to the
> routine that aren't able to be resolved by the linker. One obvious reason
> for this _MIGHT_ be you're not compiling the module which now contains
> that routine whereas before it was included in a different source file so
> got compiled transparently. A reason for that could be as simple as you
> forgot to add the file in your dependency list in a makefile.

What I am cheering for is:

Subroutine DCpZeros()
c *************************************
use DIM
use ABSCISAE
use VVALUES
use DCP
use LST2
use PARM
use maxDIMEN
use CRT
implicit none
......................
External Dcpval
real Dcpval

If Dcpval is a module procedure the last two lines would
cause a link error. My recommendation: try commenting
them out and see if the error goes away.

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


glen herrmannsfeldt

unread,
Apr 21, 2009, 1:16:54 PM4/21/09
to
monir <mon...@mondenet.com> wrote:
> On Apr 20, 4:27?pm, dpb <n...@non.net> wrote:
(snip)

> ..This exercise is my first encounter with the (F90) module feature.
> As such, I'm using the 'simplest' form of modules, basically as
> declaration sites made available to any procedure within the program
> by the USE statement. I don't believe it can be made any simpler!!

OK, since they are not module procedures then the ordinary
EXTERNAL rules should be applicable.



> 5>> 7) Below is the latest (unsuccessful) attempt which produces 1)
> above.
> ,>(snipped, mostly because without the contents of the USEd
> ,>modules I can't do anything with it. Can you make a simpler
> ,>example without any USE that demonstarates the error?
> ..Will certainly try. *Without any USE* will take me back to the F77
> working version of the program (using common blocks).
> Will strip the program of all its developer's comments, which
> hopefully would bring it down to about 2,000 lines of code, and then
> try varying combinations of routines and select (for posting) the
> simplest combination that mimics the compilation/linker problem.

OK, but there aren't that many variables in the code shown.
If the problem is really in the code you show then with enough
module code to declare the variables shown it should compile and run.

I did remove the USE statements, declare the variables that
were left, and compile it without any undefined external references.



> dpb wrote:
> 6>I would suggest (as did Glen) you take a make a toy application of
> about
> ,>three lines -- a main program that calls a routine w/ the passed
> ,>function argument but stripped down of the ancillary data and so on

(snip)

You say that there aren't any other reference to dcpval.

You might try

grep -i dcpval *.f90

to be sure.

-- glen

monir

unread,
Apr 21, 2009, 2:18:20 PM4/21/09
to
On Apr 21, 11:45 am, "James Van Buskirk" <not_va...@comcast.net>
wrote:

> What I am cheering for is:
>
>    Subroutine DCpZeros()
> c *************************************
>  use DIM
>  use ABSCISAE
>  use VVALUES
>  use DCP
>  use LST2
>  use PARM
>  use maxDIMEN
>  use CRT
>     implicit none
> ......................
>   External Dcpval
>   real Dcpval
>
> If Dcpval is a module procedure the last two lines would
> cause a link error.  My recommendation: try commenting
> them out and see if the error goes away.
>

James;

1) BRILLIANT recommendation !! It works. Thank you very much!
The question now is: Is Dcpval really a "module procedure" ??

2) As posted earlier, Module CRT is shared ONLY by Sub DCpZeros() and
Fun dcpval, and I'm using the 'simplest' form of modules, basically as


declaration sites made available to any procedure within the program
by the USE statement.

'dcpval' function name is only referenced in Sub DCpZeros in the

ZBRENT expressions. No where else in the program does the name of the


function DCpval appear (except of course in the function itself).

3) Here what I've.
!...............
Module CRT
integer :: n
real, allocatable :: xcrt(:),ycrt(:)
End Module CRT

!************************************************************
SUBROUTINE DCpZeros()
!************************************************************


use DIM
use ABSCISAE
use VVALUES
use DCP
use LST2
use PARM
use maxDIMEN
use CRT
implicit none

! EXTERNAL DCPVAL ! as per James recom. Apr 21
! real DCPVAL ! as per James recom. Apr 21

!...............
cpyzero(2,1) = ZBRENT(DCPVAL,theta(i,j+1,k),theta(i,j+1,k+1),tol)
!...............
Return
End

!**********************************
Real FUNCTION ZBRENT(func, x1, x2, tol)
!**********************************
implicit none

External func
real :: func

integer :: itmax, iter
real :: x1, x2, tol
real :: eps,a,b,c,d,e,fa,fb,fc
real :: tol1, xm, s,p,q,r

PARAMETER (itmax=100,eps=3.E-8)
a = x1
b = x2


fa = func(a)
fb = func(b)

!......................
ZBRENT = b

Return
End Function Zbrent

!****************************
Real FUNCTION dcpval(X)
!****************************


use maxDIMEN
use CRT
use Y2AA
implicit none

!...............
dcpval = y
Return
END Function dcpval

4) Based on the above:
DOES 'Dcpval' QUALIFY here as a 'MODULE PROCEDURE' ??

Thank you once again for your tremendous help.
Monir

monir

unread,
Apr 21, 2009, 5:08:24 PM4/21/09
to
On Apr 21, 1:16 pm, glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
> monir <mon...@mondenet.com> wrote:
> > On Apr 20, 4:27?pm, dpb <n...@non.net> wrote:

Glen;

Tremendous in-depth understanding of the subject with clear writing
and precise suggestions. Greatly appreciated.

>OK, since they are not module procedures then the ordinary
>EXTERNAL rules should be applicable.

>OK, but there aren't that many variables in the code shown.

...Please review my reply to James (Apr 21, 11:45 am).
He suggested:
"If Dcpval is a module procedure ... delete the declaration *External
dcpval* from Sub DCpZeros".
It works, no more linker 'undefined reference' errors, and the
executable file is generated.

But function dcpval is NOT in a module, and thus (to me) it is NOT a
module procedure! Correct ??
Perhaps the bits of code provided in my reply to James explain my
point.

As I've just suggested to dpb if a 'simplified version' of the program
helps to clarify, I'd be more than happy to post it.

>You say that there aren't any other reference to dcpval.
>You might try
>grep -i dcpval *.f90
>to be sure.

I'm absolutely sure, but will try the command.

Kind regards.
Monir

monir

unread,
Apr 21, 2009, 5:15:59 PM4/21/09
to
> On Apr 21, 1:16 pm, glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
> > > On Apr 20, 4:27?pm, dpb <n...@non.net> wrote:
>
dpb;

Thank you kindly for taking the time to reply in such a clear and
precise way.

>Clearly from the link messages, there are unsatisfied references to the
>routine that aren't able to be resolved by the linker.

>A reason for that could be as simple as you forgot to add the file in your
>dependency list in a makefile.

>You can place the dummy function in a module but keep it simple--
>the point is to simply duplicate the outline of the problem to uncover
>the reason for confusing the linker or why the piece is missing,
>_not_ to make a working application at this point.

>And, of course, if after the first step you still duplicate the problem,
>_then_ you will have a small enough application you can post the whole
>thing for others to dissect with enough context to actually be able to
>really help.

...I was almost done with a simplified version of the program by
stripping the code from all developer's comments, most executable
statements, etc. but mentaining program structure, modules, relevant
declarations, and 'critical' sub calls & fun expressions, when James
Van Buskirk replied with a brilliant suggestion:
" ... delete External dcpval from Sub DCpZeros."
It works!!!!!!!!!! No more linker undefined reference errors.

Please review my reply to James (Apr 21, 11:45 am). Keep in mind that
Function dcpval is NOT in a module as demonstrated by the bits of code
provided in my reply to James.

Regards.
Monir

dpb

unread,
Apr 21, 2009, 5:33:53 PM4/21/09
to
monir wrote:
...

> Please review my reply to James (Apr 21, 11:45 am). Keep in mind that
> Function dcpval is NOT in a module as demonstrated by the bits of code
> provided in my reply to James.

I saw it.

From what you posted that it would qualify as a module procedure, I agree.

_BUT_, while the error has gone away and it (apparently) _seems_ to
work, do you really understand why and the reason of the error? From
the portion of code posted, I don't as, like you, I'm puzzled why the
proper conclusion drawn by Glen given his hypothesis is correct, what
you posted afaict negates the assumption.

So, again from the partial code posted, I don't see the underlying cause.

Imo, it would still be worthwhile to pare it down to the minimum
structure to reproduce the problem and see if the same "fix" makes it go
away and post that entire sample for perusal. It may be an obvious
problem when seen in its entirety, but the description of the problem
and the solution so far to me aren't satisfying.

--


dpb

unread,
Apr 21, 2009, 5:52:58 PM4/21/09
to
dpb wrote:
...

> From what you posted that it would qualify as a module procedure, I agree.
...
Ooops...that was intended to be "NOT qualify", sorry.

--

kar...@comcast.net

unread,
Apr 21, 2009, 5:56:46 PM4/21/09
to
On Apr 21, 11:18 am, monir <mon...@mondenet.com> wrote:
> On Apr 21, 11:45 am, "James Van Buskirk" <not_va...@comcast.net>
> wrote:
>
>
>
> > What I am cheering for is:
>
> >    Subroutine DCpZeros()
> > c *************************************
> >  use DIM
> >  use ABSCISAE
> >  use VVALUES
> >  use DCP
> >  use LST2
> >  use PARM
> >  use maxDIMEN
> >  use CRT
> >     implicit none
> > ......................
> >   External Dcpval
> >   real Dcpval
>
> > If Dcpval is a module procedure the last two lines would
> > cause a link error.  My recommendation: try commenting
> > them out and see if the error goes away.
>
> James;
>
> 1) BRILLIANT recommendation !! It works. Thank you very much!
> The question now is: Is Dcpval really a "module procedure" ??

See below.

> 2) As posted earlier, Module CRT is shared ONLY by Sub DCpZeros() and
> Fun dcpval,

Which is total irrelevant to the issute

> 'dcpval' function name is only referenced in Sub DCpZeros in the
> ZBRENT expressions.  No where else in the program does the name of the
> function DCpval appear (except of course in the function itself).
>

(snip)


> !************************************************************
>  SUBROUTINE DCpZeros()
> !************************************************************
>  use DIM
>  use ABSCISAE
>  use VVALUES
>  use DCP
>  use LST2
>  use PARM
>  use maxDIMEN
>  use CRT
>      implicit none
>
> ! EXTERNAL DCPVAL ! as per James recom. Apr 21
> ! real DCPVAL     ! as per James recom. Apr 21
>
> !...............
>   cpyzero(2,1) = ZBRENT(DCPVAL,theta(i,j+1,k),theta(i,j+1,k+1),tol)
> !...............
> Return
> End

If the above code is a true representation of the complete code,
then DCPVAL must appear in one of the USEd modules; otherwise,
the IMPLICIT NONE should cause the compiler to complain that
DCPVAL has no type or is unknown.

I suspect that you are using Fortran terminology in a imprecise
manner, which is leading to all sorts of confusion. Can you put
your complete code that exhibits the problem someplace where
people can down load the code? Then post the URL. Your
interpretations of what you think is happening and reality are
clearly at odds. After 21 days and 90 posts, it may be prudent
to just show us everything and letting us decide what the
problems are.

--
steve

Richard Maine

unread,
Apr 21, 2009, 5:57:39 PM4/21/09
to
dpb <no...@non.net> wrote:

> So, again from the partial code posted, I don't see the underlying cause.

Me neither. The data posted leaves me completely mystified about what is
going on, and I do claim to have a pretty good knowledge of Fortran. The
voodoo magic of "this change fixed it" didn't tell me anything about
what the problem actually was.

If it were my own code, I would not accept that as an answer. Problems
that just "go away" for unexplained reasons all too often aren't really
gone, but are in hiding ready to bite you later.

You need to understand *WHY* that fixed it. As dpb noted, such
understanding probably requires simplification. Heck, the answer might
even be burried somewhere in all the postings that have been made, but
even if it is, finding it is too much work for me.

kar...@comcast.net

unread,
Apr 21, 2009, 6:08:20 PM4/21/09
to

The problem is Monir is using Fortran terminology in an imprecise
manner. The function may not be a module procedure, but it is most
certainly contained within a module. In his recent response to James,
the 'IMPLICIT NONE' would trigger an error if DCPVAL wasn't available
at compile time. The code will not compile. Here's a likely
interpretation
of Monir's problem in a nutshell

module abc
contains
function dcpval
real dcpval
dcpval = 1.
end function
end module abc

program main
use abc ! dcpval in abc has a mangled name, possibly
abc_MP_dcpval.
external dcpval ! Your telling the compiler to link with an
external function
real dcpval ! that has the name dcpval_, which is
unavailable.
call monir(dcpval)
end program

Now, when you comment out EXTERNAL and REAL DCPVAL above,
the contained function is resolved to the one in the CALL.

Richard Maine

unread,
Apr 21, 2009, 7:03:15 PM4/21/09
to
<kar...@comcast.net> wrote:

> The problem is Monir is using Fortran terminology in an imprecise
> manner. The function may not be a module procedure, but it is most
> certainly contained within a module.

If it is contained within a module, then it is a module procedure
(unless perhaps it is an internal one or a statement function). I'm not
sure what else you would be thinking that "module procedure" means. I'm
not sure why you say that it is "most certainly" contained within a
module. I could have sworn it was explicitly stated to not be so, but
then that might be part of the inconsistent data presented.

But I am also suspicious that some of the data given is internally
inconsistent, for any of the numerous reasons that data given by
confused people often is - they could be misunderstanding terms, talking
about different versions of the code, or who knows what.

I've largely given up trying to debug this one. Both too much data and
too little. I'm expected to go back and match up what pieces come from
prior postings, while of course, making sure to get the right version
from the right prior posting.

I'm half suspicious that some of Monir's confusions might be from
simillar causes to mine. Too much of the wrong sometimes contradictory
data. I think it needs simplification to the basics.

> Here's a likely interpretation
> of Monir's problem in a nutshell
>
> module abc
> contains
> function dcpval
> real dcpval
> dcpval = 1.
> end function
> end module abc
>
> program main
> use abc ! dcpval in abc has a mangled name, possibly
> abc_MP_dcpval.
> external dcpval ! Your telling the compiler to link with an
> external function
> real dcpval ! that has the name dcpval_, which is
> unavailable.
> call monir(dcpval)
> end program
>
> Now, when you comment out EXTERNAL and REAL DCPVAL above,
> the contained function is resolved to the one in the CALL.

Someone (possibly you) mentioned that before. That shouldn't compile. I
just tried with g95 and it didn't (even after I added the parens to the
function statement). If it does compile, I suggest submitting a bug
report. G95 correctly says

"Error: Cannot change attributes of USE-associated symbol at (1)"

kar...@comcast.net

unread,
Apr 21, 2009, 7:51:39 PM4/21/09
to
On Apr 21, 4:03 pm, nos...@see.signature (Richard Maine) wrote:
> <kar...@comcast.net> wrote:
> > The problem is Monir is using Fortran terminology in an imprecise
> > manner.  The function may not be a module procedure, but it is most
> > certainly contained within a module.
>
> If it is contained within a module, then it is a module procedure
> (unless perhaps it is an internal one or a statement function). I'm not
> sure what else you would be thinking that "module procedure" means. I'm
> not sure why you say that it is "most certainly" contained within a
> module. I could have sworn it was explicitly stated to not be so, but
> then that might be part of the inconsistent data presented.

Sorry, for adding to the confusion. I meant that the function isn't
declared in an interface block with an explicit "MODULE
PROCEDURE" statement, e.g.,

interface func
module procedure dpcval
end interface

but that the function has to be contained in a module (or
a subprogram or the main program); otherwise, the last
example posted should not compile due to the IMPLICIT
NONE.

> But I am also suspicious that some of the data given is internally
> inconsistent, for any of the numerous reasons that data given by
> confused people often is - they could be misunderstanding terms, talking
> about different versions of the code, or who knows what.
>
> I've largely given up trying to debug this one. Both too much data and
> too little. I'm expected to go back and match up what pieces come from
> prior postings, while of course, making sure to get the right version
> from the right prior posting.

Well, you and I have come to common ground, but the last
chunk of posted code simply could not compile. So, I suspect
that Monir posted his interpretation of the problem with
testing.

> I'm half suspicious that some of Monir's confusions might be from
> simillar causes to mine. Too much of the wrong sometimes contradictory
> data. I think it needs simplification to the basics.

I think that asking Monir for a simplification is a problem, because
Monir's simplification includes his interpretation of the problem.
I'd rather have a URL to the complete failing code, so I can
interpret the problem for myself.

Yeah, well, I wrote the above code off the top off my head without
testing. Yes, I know I should test before posting. gfortran emits
the same error.

--
steve

dpb

unread,
Apr 21, 2009, 8:12:46 PM4/21/09
to
kar...@comcast.net wrote:
> On Apr 21, 2:52 pm, dpb <n...@non.net> wrote:
>> dpb wrote:
>>
>> ...> From what you posted that it would qualify as a module procedure, I agree.
>>
>> ...
>> Ooops...that was intended to be "NOT qualify", sorry.
>>
>
> The problem is Monir is using Fortran terminology in an imprecise
> manner. The function may not be a module procedure, but it is most
> certainly contained within a module. ...

Ignoring the other sidebar that followed...

If it was (included in a module, that is), I surely didn't see it in the
posted code I looked at and he claimed it wasn't/isn't. Maybe as
Richard notes that was in yet a different post.

Your point of a link to the whole thing would be the other useful
alternative to the (probably futile) suggestion to simplify it enough to
post a sample/toy case directly.

--

Richard Maine

unread,
Apr 21, 2009, 10:23:33 PM4/21/09
to
<kar...@comcast.net> wrote:

> On Apr 21, 4:03 pm, nos...@see.signature (Richard Maine) wrote:
> > <kar...@comcast.net> wrote:
> > > The problem is Monir is using Fortran terminology in an imprecise
> > > manner. The function may not be a module procedure, but it is most
> > > certainly contained within a module.
> >
> > If it is contained within a module, then it is a module procedure
> > (unless perhaps it is an internal one or a statement function). I'm not
> > sure what else you would be thinking that "module procedure" means.

...


> Sorry, for adding to the confusion. I meant that the function isn't
> declared in an interface block with an explicit "MODULE
> PROCEDURE" statement

Oh. That would neven have occurred to me. Speaking of using Fortran
terminology in an imprecise manner. :-) The term "module precedure" is
actually defined in the language... and that's not what it means. In
fact, it is more the other way around - that a procedure cannot be
specified in a module procedure statement unless it is (already) a
module procedure; the module procedure statement isn't what makes it
one.

> > G95 correctly says
> >
> > "Error: Cannot change attributes of USE-associated symbol at (1)"
>

> gfortran emits the same error.

Good.

monir

unread,
Apr 22, 2009, 12:54:59 AM4/22/09
to
On Apr 21, 10:23 pm, nos...@see.signature (Richard Maine) wrote:
> <kar...@comcast.net> wrote:

Glen, dpb, Steve, Richard, James, and others;

I apologise for any confusion I might have caused by using "imprecise
Fortran terminology" and posting "bits" of code, as some have
commented.

1) Attached below is the entire program (file: Simple-PRSCAV8d-F90-
e.for) stripped down to its basic structure (~ 200 lines). I could've
removed more code or entire procedures, but I decided against that
since it might directly or indirectly add to the problem of
identifying the "real" problem and why James' suggestion works. This
should also help the reader to actually see the whole picture.

2) I DO NOT understand *WHY* commenting out the External dcpval in
the Sub DCpZeros FIXES the linker error (Item 7 below), but it works
as far as compiling/linking the program is concerned.

3) Let me first repeat couple of points highlighted in my recent
postings.
a. As you would appreciate, Function dcpval is NOT in a Module and
thus it DOES NOT qualify (to the best of my understanding) as a module
procedure.
b. Further, I'm using the 'simplest' form of modules, basically as


declaration sites made available to any procedure within the program
by the USE statement.

c. You'll notice that 'dcpval' function name is only referenced in Sub
DCpZeros in the ZBRENT expressions. No where else in the program does


the name of the function DCpval appear (except of course in the
function itself).

d. I'm NOT using INTERFACE or MakeFile.

4) In my earlier posting (Apr 20, 3:42 pm, Items 4 & 5):
"(in Sub DCpZeros) when I commented out ALL the statements that use
Function ZBRENT I got the same linker error "... undefined reference
to dcpval_".
"But when in addition I commented out the declaration External DCpval
as well, the program compiled successfully and the executable file was
generated (but of course unworkable because of commenting out the
ZBRENT expressions)."

5) I never tried the third alternative in Sub DCpZeros, i.e.; leaving
ZBRENT expressions but commenting out External dcpval.
As it turned out it would've fixed the problem as suggested earlier
today by James. I never even contemplated trying that since I was
convinced (correctly or wrongly) it would conflict with the F77
External rules.
I did however posed the question in Item 6) of the above referenced
posting:


"Could it be that there's a special F90 programming provision when a

program unit contains both USE and EXTERNAL ??"

6) The following simplified program was compiled & linked with the
command:
...>g95 -o Simple-PRSCAV8d-F90-e Simple-PRSCAV8d-F90-e.for

7) The compiler/linker displayed the following :
C:\...\LOCALS~1\Temp/ccWAbaaa.o:Simple-PRSCAV8d-F90-e.for:(.text
+0x1dc1): undefined reference to `dcpval_'
C:\...\LOCALS~1\Temp/ccWAbaaa.o:Simple-PRSCAV8d-F90-e.for:(.text
+0x1f74): undefined reference to `dcpval_'
C:\...\LOCALS~1\Temp/ccWAbaaa.o:Simple-PRSCAV8d-F90-e.for:(.data+0x4):
undefined reference to `dcpval_'

8) If the code format is distorted and it is difficult to read, please
let me know and I'd be glad to send the file as an attachment to your
email address.

Thank you all for your time and help.
Monir

=========================================
Module DIM
integer ::nPlanes,nRdim,nTHdim
End Module DIM
!.....
Module ABSCISAE
real, allocatable :: xbys(:,:,:),rbys(:,:,:)
real, allocatable :: theta(:,:,:)
End Module ABSCISAE
!.....
Module VVALUES
real, allocatable :: vxbyu(:,:,:),vrbyu(:,:,:)
real, allocatable :: vthbyu(:,:,:)
End Module VVALUES
!.....
Module LST1
CHARACTER*72 CONFIG
End Module LST1
!.....
Module LST2
integer :: NBLADE
real ::DIAM, RPM, U, XH, DLAMBDA
End Module LST2
!.....
Module PARM
real :: rad
End Module PARM
!.....
Module DVELOC
real, allocatable :: dvxbyx(:,:,:),dvxbyr(:,:,:)
real, allocatable :: dvxbyth(:,:,:)
real, allocatable :: dvrbyx(:,:,:),dvrbyr(:,:,:)
real, allocatable :: dvrbyth(:,:,:)
real, allocatable :: dvrbyrth(:,:,:)
real, allocatable :: dvthbyx(:,:,:)
real, allocatable :: dvthbyr(:,:,:)
real, allocatable :: dvthbyth(:,:,:)
real, allocatable :: dvthbyrth(:,:,:)
End Module DVELOC
!.....
Module DCP
real, allocatable :: dcpbyx(:,:,:),dcpbyr(:,:,:)
real, allocatable :: dcpbyth(:,:,:)
End Module DCP
!.....
Module CRT
integer :: n
real, allocatable :: xcrt(:),ycrt(:) !dim should be maxDIM; the
largest of nPlanes,nRdim,nTHdim
End Module CRT
!--end of Modules replacing F77 COMMON blocks----------------

!--create Modules to dimension 1D arrays based on maxDIM---
Module maxDIMEN
integer ::maxDIM
End Module maxDIMEN
!.....
Module TempWs
real, allocatable :: TEMPVX(:), TEMPVR(:), TEMPVT(:)
real, allocatable :: TEMPX(:), TEMPR(:), TEMPT(:)
real, allocatable :: WKSP(:)
integer, allocatable :: IWKSP(:)
End Module TempWs
!.....
Module XdYd
real, allocatable :: xd(:), yd(:)
End Module XdYd
!.....
Module Y2AA
real, allocatable :: Y2A(:)
End Module Y2AA
!.....

Module Work_Routines
Contains

!************************************************************
SUBROUTINE ReadInp()
!************************************************************
! here where nPlanes, nRdim, nTHdim, maxDIM are computed
use DIM
use maxDIMEN
use ABSCISAE
use VVALUES
use LST1
use LST2
use PARM
!......................
nPlanes = 10 ! computed
nRdim = 10 ! computed
nTHdim = 30 ! computed
maxDIM = max0(nPlanes,nRdim,nTHdim)

Call Allocate_stuff()
!......................
CALL ARRANGE()
!......................
Return
END Subroutine ReadInp

!************************************************************
Subroutine Allocate_Stuff()
!************************************************************


use DIM
use ABSCISAE
use VVALUES

use LST1
use LST2
use PARM
use DVELOC
use DCP
use maxDIMEN
use TempWs
use XdYd
use Y2AA

Allocate( xbys(nPlanes,nRdim,nTHdim),
1 rbys(nPlanes,nRdim,nTHdim),
2 theta(nPlanes,nRdim,nTHdim) )
Allocate( vxbyu(nPlanes,nRdim,nTHdim),
1 vrbyu(nPlanes,nRdim,nTHdim),
2 vthbyu(nPlanes,nRdim,nTHdim) )
Allocate( dvxbyx(nPlanes,nRdim,nTHdim),
1 dvxbyr(nPlanes,nRdim,nTHdim),
2 dvxbyth(nPlanes,nRdim,nTHdim),
3 dvrbyx(nPlanes,nRdim,nTHdim),
4 dvrbyr(nPlanes,nRdim,nTHdim),
5 dvrbyth(nPlanes,nRdim,nTHdim),
6 dvrbyrth(nPlanes,nRdim,nTHdim),
7 dvthbyx(nPlanes,nRdim,nTHdim),
8 dvthbyr(nPlanes,nRdim,nTHdim),
9 dvthbyth(nPlanes,nRdim,nTHdim),
* dvthbyrth(nPlanes,nRdim,nTHdim) )
Allocate(dcpbyx(nPlanes,nRdim,nTHdim),
1 dcpbyr(nPlanes,nRdim,nTHdim),
2 dcpbyth(nPlanes,nRdim,nTHdim) )
Allocate( TEMPVX(maxDIM), TEMPVR(maxDIM), TEMPVT(maxDIM),
1 TEMPX(maxDIM), TEMPR(maxDIM), TEMPT(maxDIM),
2 WKSP(maxDIM), IWKSP(maxDIM) )
Allocate( xd(maxDIM), yd(maxDIM) )
Allocate( Y2A(maxDIM) )

Return
End Subroutine Allocate_Stuff

!************************************************************
SUBROUTINE ARRANGE()
!************************************************************


use DIM
use ABSCISAE
use VVALUES

use maxDIMEN
use TempWs
!......................
DO 20 j=1,nrdim
DO 20 k=1,nthdim
DO 30 i=1, nplanes
TEMPX(i) = XBYS(I,J,K)
TEMPR(i) = RBYS(I,J,K)
TEMPT(i) = THETA(I,J,K)
TEMPVX(i) = VXBYU(I,J,K)
TEMPVR(i) = VRBYU(I,J,K)
TEMPVT(i) = VTHBYU(I,J,K)
30 CONTINUE
CALL SORT4(nplanes, TEMPX, TEMPR, TEMPT,
1 TEMPVX, TEMPVR, TEMPVT, WKSP, IWKSP)
20 CONTINUE
!......................
Return
END Subroutine Arrange

!************************************************************
SUBROUTINE DCpOnPln()
!************************************************************


use DIM
use ABSCISAE
use VVALUES

use DVELOC
use DCP
!......................
DO 10 i=1,nplanes
DO 10 j=1,nrdim
DO 10 k=1,nthdim
dcpbyx(i,j,k) = -2.0*(vxbyu(i,j,k) * dvxbyx(i,j,k))
!......................
10 CONTINUE
Return
END Subroutine DCpOnPln

!************************************************************
SUBROUTINE VelDeriv()
!************************************************************


use DIM
use ABSCISAE
use VVALUES

use DVELOC
use maxDIMEN
use XdYd

DATA PI/3.141592654/
rad = PI/ 180.0
DO 10 i=1,nplanes
DO 10 k=1,nthdim
DO 1 j = 1,nrdim
xd(j) = rbys(i,j,k)
yd(j) = vxbyu(i,j,k)
1 CONTINUE
DO 2 j = 1,nrdim
CALL CALCDERIV(xd, yd, nrdim, rbys(i,j,k), dvxbyr(i,j,k))
2 CONTINUE
!......................
10 CONTINUE
!......................
Return
END Subroutine VelDeriv

!************************************************************
SUBROUTINE DCpZeros()
!************************************************************


use DIM
use ABSCISAE
use VVALUES
use DCP
use LST2
use PARM
use maxDIMEN
use CRT

implicit none

EXTERNAL DCPVAL !comment out to fix the problem
real DCPVAL !comment out to fix the problem

integer :: class
integer :: i, J, K, m
real :: rgrid(nRdim), tgrid(nTHdim)
real :: vxgrid(nRdim,nTHdim)
real :: vrgrid(nRdim,nTHdim),vtgrid(nRdim,nTHdim)
real :: cpyzero(2,2),cpzzero(2,2)
real :: crossing(2,3),denominator
real :: RO
real :: accx, accr, acct
real :: dcpdymid, dcpdzmid
real :: Xp, Rp, THp, tol
real :: vxcentre, vrcentre, vtcentre
real :: yy1,yy2,yz1,yz2,zy1,zy2,zz1,zz2
LOGICAL cross1, cross2

DO 9999 i=1,nplanes
CALL NewP()
!......................
DO 9997 J=1, NRDIM
DO 9997 K=1, NTHDIM
VXGRID(J,K) = VXBYU(I,J,K)
VRGRID(J,K) = VRBYU(I,J,K)
VTGRID(J,K) = VTHBYU(I,J,K)
RGRID (J) = RBYS (I,J,K)
TGRID (K) = THETA(I,J,K)
9997 CONTINUE
!......................
DO 51 m=1,nthdim
xcrt(m) = theta(i,j+1,m)
ycrt(m) = dcpbyr(i,j+1,m)
51 Continue
n = nthdim
cpyzero(1,1) = rbys(i,j+1,k)

call Allocate_VarCRT()
cpyzero(2,1) = ZBRENT(DCPVAL,theta(i,j+1,k), theta(i,j+1,k+1),tol)

DO 52 m=1,nrdim
xcrt(m) = rbys(i,m,k+1)
ycrt(m) = dcpbyr(i,m,k+1)
52 Continue
n = nrdim
cpyzero(2,2) = theta(i,j,k+1)

call Allocate_VarCRT()
cpyzero(1,2) = ZBRENT(DCPVAL,rbys(i,j,k+1), rbys(i,j+1,k+1),tol)
!......................
denominator = yy1 - yy2
IF(ABS(denominator) .LT. 1.E-8) THEN
GOTO 9999
!......................
Xp = XBYS(I,1,1)
Rp = sqrt( crossing(1,2)**2 + crossing(2,2)**2 )
THp= ATAN2( crossing(2,2) , crossing(1,2) ) / RAD
call polin2
(rgrid,tgrid,vxgrid,nrdim,nthdim,Rp,THp,vxcentre,accx)
!......................
9999 CONTINUE
Return
END Subroutine DCpZeros

!************************************************************
Subroutine Allocate_VarCRT()
!************************************************************
use CRT
Allocate(xcrt(n), ycrt(n) )

Return
End Subroutine Allocate_VarCRT

!****************************
Real FUNCTION dcpval(X)
!****************************

use maxDIMEN
use CRT
use Y2AA

implicit none

real :: x, y, d1, dn

IF (n .LT. 3) PAUSE 'in Fun DCPVAL: n smaller than 3'
CALL DERIVPOL(Xcrt, Ycrt, 3, Xcrt(1), d1)
CALL DERIVPOL(Xcrt(n-2), Ycrt(n-2), 3, Xcrt(n), dn)
CALL SPLINE(Xcrt, Ycrt, n, d1, dn, Y2A)


CALL SPLINT(Xcrt, Ycrt, Y2A, n, x, y)

dcpval = y
Return
END Function dcpval

!************************************************************
SUBROUTINE NewP()
!************************************************************
use DIM
use LST1
use LST2
!......................
Return
END Subroutine NewP

!************************************************************
SUBROUTINE POLINT(xa, ya, n, x, y, dy)
!************************************************************
use maxDIMEN

DIMENSION xa(n),ya(n),c(maxDIM),d(maxDIM)

ns = 1
dif = ABS(x - xa(1))
!......................
Return
END Subroutine POLINT

!************************************************************
SUBROUTINE POLIN2(x1a, x2a, ya, m, n, x1, x2, y, dy)
!************************************************************
parameter (nmax=30, mmax=30)
dimension x1a(m), x2a(n), ya(m,n), yntmp(nmax), ymtmp(mmax)
!......................
do 12 j=1, m
do 11 k=1, n
yntmp(k) = ya(j,k)
11 continue
call polint (x2a, yntmp, n, x2, ymtmp(j), dy)
!......................
12 continue
call polint (x1a, ymtmp, m, x1, y, dy)

Return
End Subroutine Polin2

!**********************************
Real FUNCTION ZBRENT(func, x1, x2, tol)
!**********************************
implicit none

External func
real :: func, x1, x2, tol
integer :: itmax, iter


real :: eps,a,b,c,d,e,fa,fb,fc
real :: tol1, xm, s,p,q,r

PARAMETER (itmax=100,eps=3.E-8)

a = x1
b = x2

fa = func(a)
fb = func(b)

!......................
ZBRENT = b

Return
End Function Zbrent

!************************************************************
SUBROUTINE POLCOF(XA, YA, N, COF)
!************************************************************
PARAMETER (NMAX=30)
DIMENSION XA(N), YA(N), COF(N), X(NMAX), Y(NMAX)

DO 11 J=1,N
X(J) = XA(J)
Y(J) = YA(J)
11 CONTINUE
DO 14 J = 1,N
CALL POLINT(X, Y, N+1-J, 0., COF(J), DY)
!......................
14 CONTINUE

Return
End Subroutine Polcof

!************************************************************
SUBROUTINE DDPOLY (C, NC, X, PD, ND)
!************************************************************
DIMENSION C(NC),PD(ND)

PD(1) = C(NC)
DO 11 J = 2,ND
PD(J) = 0.
11 CONTINUE
!......................

Return
End Subroutine Ddpoly

!************************************************************
SUBROUTINE DERIVPOL (xa, ya, n, x, dy)
!************************************************************
PARAMETER (nmax=30)
DIMENSION xa(n),ya(n),cof(nmax),pd(nmax)

CALL POLCOF(xa, ya, n, cof)
CALL DDPOLY(cof, n, x, pd, 2)
dy = pd(2)

Return
End Subroutine Derivpol

!************************************************************
SUBROUTINE SPLINE(X, Y, N, YP1, YPN, Y2)
!************************************************************
PARAMETER (NMAX=100)
DIMENSION X(N), Y(N), Y2(N), U(NMAX)

IF (YP1 .GT. .99E30) THEN
Y2(1) = 0.
U(1) = 0.
ELSE
Y2(1) = -0.5
U(1) = (3./(X(2) - X(1))) * ((Y(2)-Y(1))/(X(2)-X(1))-YP1)
ENDIF
!......................
Return
End Subroutine Spline

!************************************************************
SUBROUTINE SPLINT(XA, YA, Y2A, N, X, Y)
!************************************************************
DIMENSION XA(N), YA(N), Y2A(N)

KLO = 1
KHI = N

1 CONTINUE
IF (KHI - KLO .GT. 1) THEN
K = (KHI + KLO) / 2
!......................
GOTO 1
ENDIF
!......................
Return
End Subroutine Splint

!************************************************************
SUBROUTINE SPLDERIV(XA, YA, Y2A, N, X, DY)
!************************************************************
DIMENSION XA(N), YA(N), Y2A(N)

KLO = 1
KHI = N

1 CONTINUE
!......................
Return
End Subroutine Splderiv

!************************************************************
SUBROUTINE CALCDERIV (XA, YA, N, x, dy)
!************************************************************
PARAMETER (nmax=30)

REAL x, dy, d1, dn
DIMENSION XA(n), YA(n), Y2A(nmax)

IF (n .LT. 3) PAUSE 'sub CALCDERIV: n smaller than 3'

CALL DERIVPOL(XA, YA, 3, XA(1), d1)
!......................
CALL SPLINE(XA, YA, n, d1, dn, Y2A)
CALL SPLDERIV(XA, YA, Y2A, n, x, dy)
Return
End Subroutine Calcderiv

!************************************************************
SUBROUTINE INDEXX (N, ARRIN, INDX)
!************************************************************
DIMENSION ARRIN(N), INDX(N)

DO 11 J=1, N
INDX(J) = J
11 CONTINUE
!......................
INDX(I) = INDXT
!......................
Return
End Subroutine Indexx

!************************************************************
SUBROUTINE SORT4 (N, RA, RB, RC, RD, RE, RF, WKSP, IWKSP)
!************************************************************
DIMENSION RA(N), RB(N), RC(N), RD(N), RE(N), RF(N)
DIMENSION WKSP(N), IWKSP(N)

CALL INDEXX (N, RA, IWKSP)
!......................
Return
End Subroutine Sort4

End Module Work_Routines

!>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
PROGRAM PRSCAV8d_F90
!<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
! $$ Compiled with Fortran g95 on Toshiba

! This is the 2D EULER version
! Attempt to Convert my working (F77, g95) 2D EULER procedure
PRSCAV8d.for to F90

! To Run: Requires SEQUENTIAL Input data files:
! MESHVEL1.DAT
! MESHVEL2.DAT
! which're output from my HTDBS10WEx_9 runs

C Data flow between F77 Common Blocks: used same names for F90 modules

c Common Block Its Variables Shared by
c Name: Computed in: Program Units:
c =============================================
c ABSCISAE.......ReadInp.........main, ARRANGE,
c ...............................DcpOnPln, VelDeriv,
c ...............................DCpZeros
c VVALUES........ReadInp.........main, ARRANGE,
c ...............................DcpOnPln, VelDeriv,
c ...............................DCpZeros
c DIM............ReadInp.........main, ARRANGE,
c ...............................DcpOnPln, VelDeriv,
c ...............................DCpZeros, NewP
c LST1...........ReadInp.........NewP
c LST2...........ReadInp.........DcPZeros, NewP
c PARM...........ReadInp.........DcPZeros
c DVELOC.........VelDeriv........main, DcpOnPln
c DCP............DcpOnPln........main, DCpZeros
c CRT............DCpZeros........Fun dcpval

use DIM
use ABSCISAE
use VVALUES

use DVELOC
use DCP
use Work_Routines

CALL ReadInp()
CALL VelDeriv()
!......................
CALL DCpOnPln()
!......................
CALL DCpZeros()
!......................
END Program PRSCAV8d_F90

James Van Buskirk

unread,
Apr 22, 2009, 3:02:46 AM4/22/09
to

> Module Work_Routines
> Contains
...
> SUBROUTINE DCpZeros()
...

> EXTERNAL DCPVAL !comment out to fix the problem
> real DCPVAL !comment out to fix the problem
...

> IF(ABS(denominator) .LT. 1.E-8) THEN
> GOTO 9999
...
> END Subroutine DCpZeros
...
> Real FUNCTION dcpval(X)
...
> End Module Work_Routines

Well, there's the mystery. Aside from the error that the block if
is not closed (should maybe be an end if after goto 9999) and some
issues with mixing fixed format and free format code, we see that
dcpval is in fact a module procedure. After all, I told you so :)
Most (all?) of his procedures are in module Work_Routines.

Here's Steve's example adapted to this situation:

C:\gfortran\clf\dcpval>type abc.f90
module abc
contains
function dcpval()
implicit none


real dcpval
dcpval = 1.
end function

subroutine sub
! The example has host association, not use association, so we
! can override it!
! use abc ! dcpval in abc has a mangled name, possibly
abc_MP_dcp
val.
implicit none


external dcpval ! Your telling the compiler to link with an external
functio
n
real dcpval ! that has the name dcpval_, which is unavailable.
call monir(dcpval)

end subroutine sub

subroutine monir(x)
implicit none
interface
function x()
implicit none
real x
end function x
end interface
end subroutine monir
end module abc

program main
use abc
call sub
end program

C:\gfortran\clf\dcpval>gfortran abc.f90 -oabc
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp/ccCQ6tcP.o:abc.f90:(.text+0x15):
undefined re
ference to `dcpval_'
collect2: ld returned 1 exit status

Richard Maine

unread,
Apr 22, 2009, 3:37:41 AM4/22/09
to
monir <mon...@mondenet.com> wrote:

> On Apr 21, 10:23 pm, nos...@see.signature (Richard Maine) wrote:
> > <kar...@comcast.net> wrote:
>
> Glen, dpb, Steve, Richard, James, and others;
>
> I apologise for any confusion I might have caused by using "imprecise
> Fortran terminology" and posting "bits" of code, as some have
> commented.
>
> 1) Attached below is the entire program (file: Simple-PRSCAV8d-F90-

> e.for) stripped down to its basic structure (~ 200 lines)....

Ok. I broke down and spent a bit of time digging into it using nothing
but this code. I timed it. Took 13 minutes. :-) Not counting the time to
write this post.

I (prudently, as it turned out) ignored all of the explanatory comments
about the code. In fact, I didn't even read em until after I found the
bug. I just took the code as is with nothing else.

But for some suspense, first the trivial parts.

1. This looks to be in some kind of nonstandard source form. It mostly
looks like fixed source form. The continuations look that way, and there
are some "C" comment lines. But things aren't in the right columns for
that. I don't know whether that got messed up in posting or whether this
started life as some kind of nonstandard tab source form. Anyway, I
spent most of my time fixing that as whatever form this is won't compile
for me. Although it looks more like fixed source form, I found it easier
to convert to free source form as that involved changing fewer lines.
Mostly just changed the continuations and deleted the "C" comment lines.

I also fixed a few line wraps that were probably posting artifacts.

2. Tnen g95 told me

9999 CONTINUE
1
Error: End of nonblock DO statement at (1) is within another block

and

END Subroutine DCpZeros
1
Error: Expecting END IF statement at (1)

Both of these are because there is a block IF statement without an
ENDIF.

The compiler didn't bitch about that? Really? I'd find that shocking...
enough so to make me wonder whether this file was actually fed to a
compiler exactly in this form. If it was, and the compiler didn't bitch
about that, submit a bug report.

I guessed that

IF(ABS(denominator) .LT. 1.E-8) THEN
GOTO 9999

was intended to be

IF(ABS(denominator) .LT. 1.E-8) GOTO 9999

3. Then the thing compiled and got a simillar linker error to the one
you described. About 30 seconds of my time found the source of that one.

</begin standard universal rant>

As should not be a surprise, we have here case number 5 bazzillion and
42 of one of the things that I and others bitch about the most when
trying to help debug things. It has even been bitched about (multiple
times) in this particular thread.

Do *NOT*, I repeat *NOT* try to tell us what you think is happening and
show what you think are the relevant parts of the code. If you
understood what was hapening and what things were relevant, then you
wouldn't need to ask for help.

*SHOW* us instead of telling us.

I *CAN NOT* emphasize this too much. And yes, I am yelling.

No, you are far from the only person to do this. That's why it is the
"standard universal rant".

</end standard universal rant>

In this case

> a. As you would appreciate, Function dcpval is NOT in a Module

As I appreciate when I look at the code instead of listening to the
description, function dcpval *IS SO* in a module. Observe the "module
work_routines" and "end module work_routines" statements and the
position of function dcpval between them. If you had actually shown the
code instead of incorrectly explaining that it was not in a module,
there would have been a whole lot less time wasted on this. Note my
information above that it took me 13 minutes. Probably 10 of those 13
minutes were fixing the source form.

That pretty much explains most of this. It is actually pretty simillar
to the case that Kargl showed, except that in this case, dcpzeros
accesses dcpval by host association instead of USE association, which
explains why there is no compile-time error message. (Overriding a
host-associated name is allowed; overriding a USE-associated one is
not).

The bug is that, as suggested by Kargls, the EXTERNAL statement tells
the compiler to assume that dcpval is an external procedure. It isn't.
Instead it is a module procedure. The REAL statement has simillar
issues.

It is loading more messages.
0 new messages