Created
January 7, 2016 11:59
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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, whilefoo_multiply_foo
is pure: this is the mismatch. If theassignment
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?