Created
January 7, 2016 15:06
-
-
Save szaghi/f4f521b6130ee911348f to your computer and use it in GitHub Desktop.
A (hopefully) simple test of mismatched abstract/concrete interfaces of Fortran abstract type. This should not compile at all
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 | |
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
In this example, both operator and assignment are mismatched between the abstract definition and the corresponding concrete extension: the abstract procedures are defined impure while the concrete extensions are defined pure.
GNU gfortran 5.2
Compiling with GNU gfortran (gcc v5.2), the compiler does not compile and provides:
Intel ifort 15.0.3
Compiling with Intel Fortran Compiler (v15.0.3), the compiler compile and provides the expected result (6):
Which is the correct behavior?
Note
If you modify the example declaring pure the abstract assignment procedure, GNU gfrotran behaves like Intel Compiler.