Absoft User Forum

Support => General => Topic started by: Mike Linacre on February 28, 2021, 08:07:14 PM

Title: USE module except an entity - is this possible?
Post by: Mike Linacre on February 28, 2021, 08:07:14 PM
Have successfully constructed a USE module with 500 interfaces :-)

Now wish to use this module in each of the 500 subroutines/functions to check the interfaces to the other 499, but the Absoft compiler says for each one:
"xxx" is the name of this program unit, therefore must not be associated from module "myinterfaces"

Yes, we can select only some interfaces:
use module-name, only: only-list

Can we do the opposite, exclude only some?
use module-name, except: except-list

However, I have implemented an only-list in each program unit listing the other 499 units . This is done as 500 include files, a different one for each program unit. This is working fine :-)

Thanks ....
Title: Re: USE module except an entity - is this possible?
Post by: forumadmin on March 01, 2021, 10:11:33 AM
Can you provide a small example with a few routines that reproduces the error?

It may be that I don't understand what you are trying to do, but this code compiles without any errors:

module iface
  interface
      function add(a,b) result(c)
        implicit none       
        real(4) :: a,b,c
      end function add
 
      function mult(a,b) result(c)
        implicit none
        real(4) :: a,b,c
      end function mult
  end interface
end module iface

function add(a,b) result(c)
  use iface
  implicit none
  real(4) :: a,b,c
  c = a + b
end function add

function mult(a,b) result(c)
  use iface
  implicit none
  real(4) :: a,b,c
  c = a * b
end function mult




Title: Re: USE module except an entity - is this possible?
Post by: mecej4 on March 10, 2021, 09:34:19 PM
A compiler may internally generate interfaces to subprograms that it has scanned and check that later invocations of the subprogram adhere to the previously seen interface, but the programmer is not currently allowed to include an "interface to itself". The Fortran 2018 standard has this to say:

C1501 (R1501) An interface-block in a subprogram shall not contain an interface-body for a procedure defined by that subprogram.


The compiler accepts the code that you provided, but it does not seem to actually check it for consistency. I changed the type declarations in the interface to MULT to:
Code: [Select]
        real(4) :: a,b
        logical :: c   ! Error in type
and the compiler ignored the "logical" being inconsistent with the actual type of c, i.e., real(4).
Title: Re: USE module except an entity - is this possible?
Post by: forumadmin on March 11, 2021, 07:57:42 AM
The Fortran 95 standard has the same statement.  You are correct, the compiler is not going to check the arguments in the case you brought up. It will check for argument mismatches for any of the other routines from the module that are called from the routine being defined, but does not verify that the argument types match for the routine currently being defined.

I included the example to show what I thought you were trying to do in your code. I asked for a small example that reproduced the error you are getting because I was unable to come up with one.
   
 
Title: Re: USE module except an entity - is this possible?
Post by: Stu on March 31, 2021, 11:17:11 AM
Had that issue with an API module I use.  Rather than USE only, have you tried locally renaming the function so that it doesn't conflict?  Works on ifort and gfortran.

INTEGER FUNCTION exampleFunction RESULT(theResult)

USE my_module, hideFn => exampleFunction

Title: Re: USE module except an entity - is this possible?
Post by: Mike Linacre on April 08, 2021, 09:17:00 PM
Thanks, Stu. You solved it! Here is another example: Use Except ...

                SUBROUTINE actual_name (parameter list)
                USE my_interface_module, dummy_name => actual_name

Also to check that my_interface_module is correct, I copied and compiled all routines:

                SUBROUTINE xxactual_name (parameter list)
                USE my_interface_module
               (original code unchanged here)
                CALL  actual_name (same parameter list)
                END
   
Is there an easier way ??