How do you specify a module variable as a part of dummy argument declaration inside an interface block?

nougako

I have a subroutine sub_x defined as

subroutine sub_x(n, a)
  use, intrinsic :: iso_c_binding
  use mod_a, only : m
  implicit none
  integer(c_long), intent(in) :: n
  real(c_double), intent(in) :: a(1:m)
  .
  .
  .
  rest of the codes
  .
  .

That is, sub_x depends on a module variable m as an extent of its array argument. Now, in a separate file, the interface block of sub_x goes as follows

module mod_x
  use, intrinsic :: iso_c_binding
  
  interface
     subroutine sub_x(n, a)
       import :: c_long, c_double, m
       integer(c_long), intent(in) :: n
       real(c_double), intent(in) :: a(1:m)
     end
  end interface
end module mod_x

And any procedure calling sub_x will have a use mod_x statement. When trying to compile the file containing module mod_x, file_x.f90 with ifort -c file_x.f90 I got error saying "IMPORT-name must be the name of an entity in the host scoping unit. [m]" showing that the compiler was not able to resolve m. It may be able to resolve c_long and c_double because of the presence of use, intrinsic :: iso_c_binding in mod_x definition, but I may be wrong. Adding use mod_a, only : m in mod_x definition may solve the issue, but that means mod_x will depend on mod_a and I try to avoid dependency between modules.

One way that seems to work is to move the interface block to a plain text file, say interface_x.f90, and add an include "interface_x.f90" line in any procedure calling sub_x. But I try to avoid using this method because I have tens of external subroutines and it's better to have the interfaces of all of them in a single file. If I were to use this, just about any procedure having an include "interface_x.f90" will have to have use mod_a, only : m even though it doesn't need m. What's the solution?

francescalus

It is not necessary to use an import statement to make an entity accessible in an interface block. It is one way, and in some cases the only way. This is not one of those cases.

The import statement controls accessibility of entities from the host scope of a scoping block (such as an interface block). In the (simplified) case of the question

module mod_x
  use, intrinsic :: iso_c_binding
  
  interface
     subroutine sub_x()
       import :: c_long
     end
  end interface
end module mod_x

the import statement makes the entity c_long from the module scope accessible in the interface specification of sub_x. That entity is itself available in the module scope because it is use associated from the module iso_c_binding.

Exactly the same entity is made accessible in the interface specification by

module mod_x
  interface
     subroutine sub_x()
       use, intrinsic :: iso_c_binding, only : c_long
     end
  end interface
end module mod_x

This is much as in the actual subroutine specification of sub_x. m can be made accessible in the same way:

module mod_x
  interface
     subroutine sub_x(n, a)
       use, intrinsic :: iso_c_binding, only : c_long, c_double
       use mod_a, only : m
       integer(c_long), intent(in) :: n
       real(c_double), intent(in) :: a(1:m)
     end
  end interface
end module mod_x

(Or equivalently by combining an import with use mod_a in the module scope.)

Note that this is a module dependency whichever way you write it: mod_x depends on mod_a because the interface specified in mod_x has a characteristic determined by an entity in mod_a.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

How do you update an instance variable within an if block?

Apply function to grouped data frame in Dask: How do you specify the grouped Dataframe as argument in the function?

How do you structure imports for testing inside a module of your project?

How do you check if a variable is defined inside a module in Julia?

How do you load a module @everywhere inside a function in Julia

Is a declaration of a variable inside a block also a definition?

how to extend interface/class on variable declaration

In a Camunda embedded form, how do you specify the bound variable scope?

How do I specify this kind of variable argument tuple with python typing?

Declaration of dummy argument explicit shape arrays in Fortran

How do you specify multiple columns for the key, as part of a hash subpartition?

How do you query for a block inside of search results?

Can you specify how an argument in an attribute is resolved?

How do you get the file referenced in the declaration of lotusscript that is part of the %INCLUDE

Using a Svelte each block, how do you bind:value to a to a variable stored outside the array, but reference inside the array?

How do you specify the type of a value in a keyof declaration?

How can you make a dummy variable based on part of a character?

How do you load a dynamic module by variable in Angular 9?

Re-declaration of block scoped loop variable inside the loop

How to access variable inside a block

How do you capture part of a regex to a variable in Ruby?

How do you modify a nodejs module variable?

How do you add an editable block of text inside a non editable block in Quill?

How do you take a part of a variable out, change it, then put it back in?

In Function Interface declaration, how to pass another Function Interface as argument?

How do you make a dummy dataset in R?

How do you create a dummy variable based on the presence of a string by date, but on a different row?

How do I specify the a specific dummy variable with SymPy Integration

How to specify an Interface for an argument when another argument is a specific value