Re: type/rank mismatch error



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.
.



Relevant Pages

  • Re: Segmentation Fault in Gauss-Legendre Subroutine
    ... So I don't know really does this subroutine works correctly or no? ... But that requires an explicit interface (which is ... most easily done by putting the routine an a module). ... Those directions, in turn ought to say something about USEing ...
    (comp.lang.fortran)
  • Re: Optional function arguments, how?
    ... Overload the interface with a stub/driver routine ... subroutine DefaultFunc!--default routine ... end module NewFun ...
    (comp.lang.fortran)
  • Re: Fast pancake flipping
    ... excerpt of my fast flipper here. ... Recently I wrote a subroutine that seemed to qualify for the ... It is certainly true that making a routine readable is usually ...
    (comp.programming)
  • Re: What routine is running
    ... argumnent a dynamic array and, with the addition of 1 line of code in the ... sub, gurarantee the existing code will work. ... duplicating an entire routine is a terrible solution. ... if the subroutine is meant to modify the value ...
    (comp.databases.pick)
  • Re: C by reference screws up character strings
    ... subroutine td8_getset ... end interface ... Now, how do I apply the C, By Reference to just these routines? ... you'll want to double-check against the C routine declaration. ...
    (comp.lang.fortran)