Skip to content

Instantly share code, notes, and snippets.

@szaghi
Created January 7, 2016 11:59
Show Gist options
  • Save szaghi/97245928de2082d0c289 to your computer and use it in GitHub Desktop.
Save szaghi/97245928de2082d0c289 to your computer and use it in GitHub Desktop.
A (hopefully) simple test of mismatched abstract/concrete interfaces of Fortran abstract type
module adt_foo_class
implicit none
private
type, abstract, public :: adt_foo
private
contains
private
procedure(sym_operator), pass(lhs), deferred :: foo_multiply_foo
procedure(assignment), pass(lhs), deferred :: assign_foo
generic, public :: operator(*) => foo_multiply_foo
generic, public :: assignment(=) => assign_foo
endtype adt_foo
abstract interface
function sym_operator(lhs, rhs) result(operator_result)
import :: adt_foo
class(adt_foo), intent(IN) :: lhs
class(adt_foo), intent(IN) :: rhs
class(adt_foo), allocatable :: operator_result
endfunction sym_operator
pure subroutine assignment(lhs, rhs)
import :: adt_foo
class(adt_foo), intent(INOUT) :: lhs
class(adt_foo), intent(IN) :: rhs
endsubroutine assignment
endinterface
endmodule adt_foo_class
module foo_class
use adt_foo_class, only : adt_foo
implicit none
private
type, extends(adt_foo), public :: foo
private
integer, public :: a = 0
contains
private
procedure, pass(lhs) :: foo_multiply_foo
procedure, pass(lhs) :: assign_foo
endtype foo
contains
pure function foo_multiply_foo(lhs, rhs) result(opr)
class(foo), intent(IN) :: lhs
class(adt_foo), intent(IN) :: rhs
class(adt_foo), allocatable :: opr
allocate(foo :: opr)
select type(opr)
class is(foo)
opr = lhs
select type(rhs)
class is (foo)
opr%a = lhs%a * rhs%a
endselect
endselect
return
endfunction foo_multiply_foo
pure subroutine assign_foo(lhs, rhs)
class(foo), intent(INOUT) :: lhs
class(adt_foo), intent(IN) :: rhs
select type(rhs)
class is (foo)
lhs%a = rhs%a
endselect
return
endsubroutine assign_foo
endmodule foo_class
program foo_adt_test
use foo_class, only : foo
implicit none
type(foo) :: foo1, foo2, foo3
foo1 = foo(2)
foo2 = foo(3)
foo3 = foo1 * foo2
print "(I2)", foo3%a
stop
contains
endprogram foo_adt_test
@szaghi
Copy link
Author

szaghi commented Jan 7, 2016

compiling this with GNU gfortran 5.2 the code is successfully compiled and it provides the expected result, namely 6.

Note that sym_operator is impure, while foo_multiply_foo is pure: this is the mismatch. If the assignment is made impure the compiler does not compile the code.

So: the mismatch is not allowed only for assignment, while is it allowed for operators?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment