Re: type/rank mismatch error
- From: "Jugoslav Dujic" <jdujic@xxxxxxxxx>
- Date: Fri, 29 Jun 2007 09:21:13 +0200
estevino@xxxxxxxxx wrote:
| Hi,
| I'm using gfortran 4.3.0 on Mac OSX 10.4.8.
| I'm having a problem compiling a two modules and a main.
| One module looks like
|
| MODULE calculate
| CONTAINS
| SUBROUTINE some_op(a,b,c)
| USE nrtype
| IMPLICIT NONE
| REAL, INTENT(IN) :: a
| REAL, DIMENSION(:), INTENT(IN) :: b
| REAL, DIMENSION(:), INTENT(OUT) :: c
| ...
| END SUBROUTINE some_op
| END MODULE calculate
|
| Another module contains several subroutines that take 'calculate' as a
| procedure argument and makes a call to the routine 'some_op' inside --
| this looks like
|
| MODULE various
| USE calculate
| CONTAINS
| SUBROUTINE number1(x,y,some_op)
| ...
| END SUBROUTINE number1
| SUBROUTINE number2(x,y,some_op)
| ...
| END SUBROUTINE number2
| END MODULE various
|
| When I try to compile the object, I get a type/rank mismatch error:
|
||| gfortran -c calculate.f90 various.f90
|
| various.f90:118.47:
|
| call number1(x,y,some_op)
| 1
| Error: Type/rank mismatch in argument 'some_op' at
| (1)various.f90:118.47:
|
| These procedures are not defined anywhere else, so I'm at a loss to
| explain why this is occurring. Any help?
I must say I'm confused as to the intent of the code. The code, as shown,
violates the simple rule that
*Any formal (dummy) argument of a routine must be declared locally
in the routine, not elsewhere*
in other words, if you defined some_op in the module "calculate", you
must not redefine some_op elsewhere (at least, not in a scope which
USEs the module "calculate")
Let's simplify the case, using something other than routine; it
is the same error (whose should be better worded by the compiler) as:
MODULE calculate
INTEGER:: some_number
END MODULE calculate
MODULE various
USE calculate
CONTAINS
SUBROUTINE number1(x,y,some_number)
Error; redefinition-----------^
Now, I'm confused as to the intent of the code. Allowing myself the
grave sin of guessing as to the intent, you want:
1) either to plainly CALL some_op from number1 and number2, in
which case you need:
MODULE various
USE calculate
CONTAINS
SUBROUTINE number1(x,y)
....
CALL some_op(x, z, f)
END SUBROUTINE number1
2) ...or, judging on your misguided (no offense intended) wording:
| Another module contains several subroutines that take 'calculate' as a
| procedure argument and makes a call to the routine 'some_op' inside --
| this looks like
[A module name, "calculate", can NOT be a procedure argument]
....you want to pass a routine of "signature" like the one of some_op
as an actual argument to the number1. In that case, you still have to
declare that signature *locally*:
MODULE various
CONTAINS
SUBROUTINE number1(x,y,some_op)
REAL, INTENT(WHATEVER):: x,y
INTERFACE
SUBROUTINE some_op(a,b,c)
USE nrtype
IMPLICIT NONE
REAL, INTENT(IN) :: a
REAL, DIMENSION(:), INTENT(IN) :: b
REAL, DIMENSION(:), INTENT(OUT) :: c
END SUBROUTINE some_op
END SUBROUTINE
END INTERFACE
!Body of number1
....
END SUBROUTINE number1
....
END MODULE Various
Note that the INTERFACE keyword specifies that you're declaring a
"placeholder", i.e. a "signature" or "prototype" of the routine, which
may have any name you want. The actual some_op will be defined in
the calling program. And no, you cannot define such interface elsewhere
than within the routine whose dummy argument it is. Fortran doesn't
have "function typedefs" or "function pointers" like C/C++.
If that's the intent, what you *can* do to save retyping of the
INTERFACE block in a zillion places, is to move it to an INCLUDEd
file, i.e.
File Calculate.fd
----------------------
INTERFACE
SUBROUTINE some_op(...)
...
END INTERFACE
----------------------
MODULE various
CONTAINS
SUBROUTINE number1(x,y,some_op)
REAL, INTENT(WHATEVER):: x,y
INCLUDE "Calculate.fd"
Note the (huge) semantic difference between INCLUDE and USE: the
former is just a "text substitution" or a "macro". The latter
always declares a "real thing".
--
Jugoslav
___________
www.xeffort.com
Please reply to the newsgroup.
You can find my real e-mail on my home page above.
.
- Follow-Ups:
- Re: type/rank mismatch error
- From: Richard Maine
- Re: type/rank mismatch error
- References:
- type/rank mismatch error
- From: estevino
- type/rank mismatch error
- Prev by Date: Re: Form k = i + j and test for overflow.
- Next by Date: Re: Need Help: compiling old Fortran program
- Previous by thread: Re: type/rank mismatch error
- Next by thread: Re: type/rank mismatch error
- Index(es):
Relevant Pages
|