Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Abstract type/concrete extension interfaces mismatch: different behavior between GNU gfortran and Intel Fortran Compiler

Stefano_Zaghi
Beginner
521 Views

Dear Great Intel Fortran developers Team,

as always, thank you very much for your great work.

I have found a different behavior between the Intel Fortran Compiler (v15.0.3) and GNU gfortran (gcc v5.2) when compiling a "possible" wrong (non standard conforming) code. The most simple (not) working example that I can provide is the following:

 

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 

There is an abstract type, namely "adt_foo", that has one deferred operator and one defined assignment defined as "impure". There is a concrete extension of the above abstract type, namely "foo", that has the corresponding operator and assignment defined as "pure". Now, I do not know if this "mismatch" is allowed by the standard (2003/2008), anyway this possible wrong code is compiled differently by Intel Fortran with respect the GNU gfortran. As a matter of facts, Intel Fortran (v15.0.3) compiles this code without warnings and the result obtained by the test is the one expected (6). On the contrary, GNU gfortran (v5.2), does not compile the code and provide the following error message:

→ gfortran foo_adt_test.f90
foo_adt_test.f90:52:13:

     opr = lhs
             1
Error: Subroutine call to ‘assignment’ at (1) is not PURE
foo_adt_test.f90:74:4:

 use foo_class, only : foo
    1
Fatal Error: Can't open module file ‘foo_class.mod’ for reading at (1): No such file or directory
compilation terminated.

 

I am not sure, but I think that GNU gfortran is right, the code is wrong. Can you give me some insights on this (possible) issue? Is the code wrong, i.e. not standard?

Note that if you modify the example declaring pure the abstract assignment procedure, GNU gfrotran behaves like Intel Compiler.

For your convenience I have created a dedicated Gist here https://gist.github.com/szaghi/f4f521b6130ee911348f#gistcomment-1664759

Thank you very much for any suggestions,

My best regards.

 

 

 

0 Kudos
6 Replies
Steven_L_Intel1
Employee
521 Views

I would argue that ifort is correct here. The standard says (12.4.3.2), emphasis mine:

32 7 If an explicit specific interface for an external procedure is specified by an interface body or a procedure declaration
33 statement (12.4.3.6), the characteristics shall be consistent with those specified in the procedure definition, except
34 that the interface may specify a procedure that is not pure even if the procedure is defined to be pure.

0 Kudos
Stefano_Zaghi
Beginner
521 Views

Dear Dr. Lionel,

thank you very much for your fast replay. Indeed, I was hoping that the Intel was the correct behavior.

From your citations I understand that the standard allow the "abstract interfaces" of deferred procedures to be defined as "impure", while their concrete extensions could be defined pure. Is my understanding correct?

Thank you very much again, Intel rocks!

My best regards. 

0 Kudos
Steven_L_Intel1
Employee
521 Views

That's my interpretation. It isn't specific to abstract interfaces - the standard says it's ok for a specific procedure to be PURE even if the interface for it doesn't say PURE. 

0 Kudos
Stefano_Zaghi
Beginner
521 Views

Ok, thank you very.

 

Your "interpretation" is very close to "God says" for me. Thank you very much again.

My best regards.

0 Kudos
Sirat_S_
Beginner
521 Views

Dear Mr Stefano Zaghi

I know this thread is about discussing something else. Yet i take opportunity to put forward a query here.

In regard to reading an INI file I have been told by one of the forum members about the parser developed by yourself.

I am using Intel Fortran compiler in the Visual Studio 8 platform. My query is whether the said parser is compatible with that background.

Pls guide.

0 Kudos
Stefano_Zaghi
Beginner
521 Views

Dear Sirat,

Thank you for interest. To answer to your question, yes, I think that the library is compatible. It should be standard compliance, thus my library should be compatible with any architectures (OS/Compiler) supporting Fortran standard (2003).

You can find it here https://github.com/szaghi/FiNeR

It is quite a bit that I have not update it. I using GNU Linux OS, thus I am not sure that it works out-of-box into Windows OS, but it should. If you can test it, I will be very happy to support your work. 

Documentation is here for API http://szaghi.github.io/FiNeR/index.html and into its wiki https://github.com/szaghi/FiNeR/wiki

As the licensing system, currently it is only GPL, but I planned to switch to a more permissive one as the one of FLAP https://github.com/szaghi/FLAP

Let me know how I can help you.

My best regards.

 

 

0 Kudos
Reply