Type-bound procedure that uses an external procedure with an explicit interface: Sometimes it compiles, sometimes not

bob.sacamento

I screwed up on my previous question and had to delete it. Here's a new one:

I got most of this code from this quite helpful site:

module shape_mod

type shape
    integer :: color
    logical :: filled
    integer :: x
    integer :: y
contains
    procedure :: initialize
end type shape

type, extends(shape) :: rectangle
        integer :: length
        integer :: width
end type rectangle

type, extends(rectangle) :: square
end type square

interface
    subroutine initialize(sh, color, filled, x, y, length, width)
        import shape
        class(shape) :: sh
        integer :: color
        logical :: filled
        integer :: x
        integer :: y
        integer, optional :: length
        integer, optional :: width
  end subroutine
end interface

end module

subroutine initialize(sh, color, filled, x, y, length, width)

    ! initialize shape objects
    class(shape) :: sh
    integer :: color
    logical :: filled
    integer :: x
    integer :: y
    integer, optional :: length
    integer, optional :: width

    ! do stuff with shape

end subroutine initialize


program drv

use shape_mod

type(shape) :: sh

call sh%initialize(1, .true., 0, 0, 5, 10)

end program

This fails to compile (as it should, as pointed out by respondents to my previous question) with the error:

gfortran shape2.f90
shape2.f90:38:16:

     class(shape) :: sh
                1
Error: Derived type ‘shape’ at (1) is being used before it is defined
shape2.f90:46:7: Error: Symbol ‘sh’ at (1) has no IMPLICIT type
shape2.f90:47:7: Error: Symbol ‘sh’ at (1) has no IMPLICIT type
shape2.f90:48:7: Error: Symbol ‘sh’ at (1) has no IMPLICIT type
shape2.f90:49:7: Error: Symbol ‘sh’ at (1) has no IMPLICIT type

So, my question is, what can I do to get subroutine initialize() to know about type shape? The only thing I can think of is to put a use statement in:

subroutine initialize(sh, color, filled, x, y, length, width)

    use shape_mod
    ! initialize shape objects
    class(shape) :: sh
    integer :: color
    logical :: filled
    ...
end subroutine initialize

But that gives me a new error:

gfortran shape2.f90
shape2.f90:37:8:

     use shape_mod
        1
Error: ‘initialize’ of module ‘shape_mod’, imported at (1), is also the name of the current program unit

How to write the subroutine is the one thing the link I referenced above does not tell. Is there a way to do this? Or does initialiaze() have to be part of shape_mod for this to work?

francescalus

In the module you have defined an interface for the external procedure initialize. When you use this module in the subroutine definition you have access to the interface of the subroutine itself.

You cannot do this.

Fortunately, you can avoid having the interface accessible by

use shape_mod, only shape

Now, the above is necessary because of the design made to use an external procedure in the type binding. In general, one would expect not to use an external procedure in this way. As we've seen, there's the additional complexity in using an external procedure, both with having to use the module where the type is defined, but also in having to manually specify the procedure's interface.

There are times where an external interface would be useful, but here the purpose of the example leading to the question was perhaps pedagogical rather than simple. There's no obvious reason here why initialize shouldn't be a module procedure.

Instead, consider the example

interface
  subroutine ext()
  end subroutine
end interface

type mytype
 contains
  procedure(iface), nopass :: ext
end type

The external subroutine ext doesn't have a passed-object dummy (the binding has nopass) so doesn't need the module in which mytype is defined. This is a simplification.

Finally, as High Performance Mark comments, perhaps initialize needn't even be a binding name. Instead a "constructor" could be used:

type mytype
end mytype

interface mytype
  procedure intialize_mytype
end interface

Details are left for the interested reader to find from other sources.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Stored Procedure sometimes returns short, sometimes returns int

PHP sqlsrv store procedure sometimes no return result

calling a type bound procedure in a PURE procedure Fortran

Stored procedure runs correctly but DataReader gets wrong result...sometimes

Why does my VBA procedure sometimes stop in debug mode?

gfortran associates wrong type-bound procedure

How are function interfaces specified in abstract interface blocks for deferred binding as a type bound procedure?

Why does Moq sometimes require explicit type declaration in Returns?

Explicit Cast From Type to Not Implemented Interface Compiles but Fails in Runtime

Procedure with assumed-shape dummy argument must have an explicit interface

Explicit typing in Groovy: sometimes or never?

Passed object as intent(inout) in a type-bound elemental procedure

Can I overload a type-bound procedure based on the number of arguments?

How to make a type-bound polymorphic pointer point to an extended type, using a parent type-bound procedure?

Stored procedure that uses cursor

Sendig explicit CURSOR as procedure parameter

Python procedure that uses another procedure returns none

mongodb distinct sometimes uses index and sometimes doesn't

Interface mismatch in dummy procedure

Error calling procedure in posgres "No procedure matches the given name and argument types. You might need to add explicit type casts."

Automatically execute type-bound procedure of abstract parent type at the end of extended type's constructor

Fortran: Separate type-bound procedure from type definition in separate files

Laravel 5.4 sometimes uses different database credentials

ColdFusion site sometimes uses wrong database

IE loads sometimes WOFF and sometimes EOT font type

Why does type Record sometimes complain about missing keys and sometimes not?

External jquery .click() event not working sometimes

Webservice sometimes does not respond to external requests

Backup folder on sometimes attached external usb harddrive