Quantcast
Channel: Intel® Fortran Compiler
Viewing all articles
Browse latest Browse all 3270

Using Generic Interfaces and Parameterized Types for selective early binding

$
0
0

I am using a parameterized type (called dispersion_type in the code) to select a function based on the value of a kind parameter of the type (namely, fkind). The different functions would have identical signatures if not for the additional argument of type dispersion_type(fkind).  With the additional argument, the functions can be collected under a  generic interface.  If the name of the generic interface is different from dispersion_type, the program works as desired.

If the name is the same, the code compiles and works with IFORT 15.0.1, but fails with IFORT 16.0.0, with the error

early_binding.f90(44): error #6593: The number of expressions in a structure constructor differs from the number of components of the derived type.   [DISPERSION_FORCE#2]

I think the code is correct though: in line 44, the second argument of dispersion_type(5., *) should call the structure constructor of dispersion_type, since there is no match available under the generic name.  The call to dispersion_type(5., *) itself should be to one of the overloaded versions available under the generic name.  It seems IFORT 16.0.0 decides there is no match and then tries to invoke the structure constructor again, which results in an error. Comments?

Module pairwise_potential
! Using a generic interface to bind procedures to parameterized types at compile times.
! The method works if the name of the type dispersion_force is DIFFERENT
! from the name of the generic interface, but it should work when the names
! are the same, too. That would be neater.
   Implicit None

   Type dispersion_force(fkind)
      Integer, Kind :: fkind = 2
   End Type dispersion_force

   Interface dispersion_force
      Module Procedure first_force
      Module Procedure second_force
      Module Procedure third_force
   End Interface dispersion_force

Contains

   Real Function first_force(rs, fkind)
      Real, Intent(In)                  :: rs
      Type(dispersion_force(1)), Intent(In) :: fkind

      first_force = 1.
   End Function first_force

   Real Function second_force(rs, fkind)
      Real, Intent(In)                  :: rs
      Type(dispersion_force(2)), Intent(In) :: fkind

      second_force = 2.
   End Function second_force

   Real Function third_force(rs, fkind)
      Real, Intent(In)                  :: rs
      Type(dispersion_force(3)), Intent(In) :: fkind

      third_force = 3.
   End Function third_force

   Subroutine verify_association
      Integer, Parameter :: fkind = 2

      Print *, 'The force kind is ', dispersion_force(5., dispersion_force(fkind)())

      !The above works with IFORT 15.0.1, but does not compile with IFORT 16.0.0
      !Furthermore, since the type dispersion_force has the default fkind=2, I expect
      !the following to also compile

      !Print*, 'The force kind is ', dispersion_force(5., dispersion_force)
      !Print*, 'The force kind is ', dispersion_force(5., dispersion_force(fkind))
   End Subroutine verify_association

End Module pairwise_potential

Program test
   Use pairwise_potential

   Call verify_association
End Program test

 


Viewing all articles
Browse latest Browse all 3270

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>