# How to get a list of module procedures

**URL:** <https://fortran-lang.discourse.group/t/how-to-get-a-list-of-module-procedures/3294>\
**Category:** Help\
**Created:** [April 22, 2022, 4:38pm UTC](https://fortran-lang.discourse.group/t/how-to-get-a-list-of-module-procedures/3294 "2022-04-22T16:38:54Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Rob777](https://avatars.discourse-cdn.com/v4/letter/r/9e8a1a/32.png) [@Rob777](https://fortran-lang.discourse.group/u/Rob777)\
**Post date:** [April 22, 2022, 4:38pm UTC](https://fortran-lang.discourse.group/t/how-to-get-a-list-of-module-procedures/3294/1 "2022-04-22T16:38:54Z")

</div>

Hello Everyone,

I’m wondering if it there is a way to have, at the start of a module, a list of all module procedures in such a way that if a procedure is not contained in that list then is not callable or the Compiler will throw an error.

I find difficult to find what procedures are contained in a module by only examining the entire module content and having to look at procedures implementations.

Thanks

---

<div class="post-metadata">

**Author:** ![milancurcic](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/milancurcic/32/2_2.png) [@milancurcic](https://fortran-lang.discourse.group/u/milancurcic)\
**Post date:** [April 22, 2022, 4:45pm UTC](https://fortran-lang.discourse.group/t/how-to-get-a-list-of-module-procedures/3294/2 "2022-04-22T16:45:49Z")

</div>

Hi Rob,

Assuming you’re the one writing the code, you could declare everything in the module as `private` (default `public`) and explicitly list `public` procedures or variables. E.g.:

```auto
module m
  implicit none
  private
  public :: sub1, sub2, ...
  ...
contains
  subroutine sub1()
    ...
  end subroutine sub1
  
  subroutine sub2()
    ...
  end subroutine sub2
  ...
end module m

```

---

<div class="post-metadata">

**Author:** ![Rob777](https://avatars.discourse-cdn.com/v4/letter/r/9e8a1a/32.png) [@Rob777](https://fortran-lang.discourse.group/u/Rob777)\
**Post date:** [April 22, 2022, 4:51pm UTC](https://fortran-lang.discourse.group/t/how-to-get-a-list-of-module-procedures/3294/3 "2022-04-22T16:51:32Z")

</div>

Thank you.

What if a procedure is implemented in the contains section but I forgot to write it on the public declaration section? When the module contains hundred of procedure missing one is easy.

What I’m searching for is for the Compiler to throw an error if the procedure is in the contains section but not in the “list” section.

---

<div class="post-metadata">

**Author:** ![Beliavsky](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Beliavsky](https://fortran-lang.discourse.group/u/Beliavsky)\
**Post date:** [April 22, 2022, 4:54pm UTC](https://fortran-lang.discourse.group/t/how-to-get-a-list-of-module-procedures/3294/4 "2022-04-22T16:54:53Z")

</div>

> [@milancurcic](#):
>
> Assuming you’re the one writing the code, you could declare everything in the module as `private` (default `public`) and explicitly list `public` procedures or variables.

Yes, and with gfortran you can use the `-Werror=unused-function` option to prevent modules with dead code (private procedures that are not invoked within the module) from being compiled. With this option, for the file

```auto
module m
implicit none
private
public :: foo
contains
subroutine foo()
print*,"in foo"
end subroutine foo
!
subroutine bar()
print*,"in bar"
end subroutine bar
end module m

```

gfortran says

```auto
private.f90:10:14:

   10 | subroutine bar()
      | ^
Error: 'bar' defined but not used [-Werror=unused-function]
f951.exe: some warnings being treated as errors

```

---

<div class="post-metadata">

**Author:** ![vmagnin](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/vmagnin/32/28_2.png) [@vmagnin](https://fortran-lang.discourse.group/u/vmagnin)\
**Post date:** [April 22, 2022, 5:00pm UTC](https://fortran-lang.discourse.group/t/how-to-get-a-list-of-module-procedures/3294/5 "2022-04-22T17:00:02Z")

</div>

> [@Rob777](#):
>
> What I’m searching for is for the Compiler to throw an error if the procedure is in the contains section but not in the “list” section.

If it is not listed in the public section and is called from outside, the compiler will print an error.  
But no error if it is not called.

---

<div class="post-metadata">

**Author:** ![Rob777](https://avatars.discourse-cdn.com/v4/letter/r/9e8a1a/32.png) [@Rob777](https://fortran-lang.discourse.group/u/Rob777)\
**Post date:** [April 22, 2022, 5:04pm UTC](https://fortran-lang.discourse.group/t/how-to-get-a-list-of-module-procedures/3294/6 "2022-04-22T17:04:15Z")

</div>

If I don’t know about the existence of that procedure I can’t even call it.

When one has hundreds of procedures it would be helpful to have them listed in top of the module with a double check from the Compiler.

Thanks

---

<div class="post-metadata">

**Author:** ![vmagnin](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/vmagnin/32/28_2.png) [@vmagnin](https://fortran-lang.discourse.group/u/vmagnin)\
**Post date:** [April 22, 2022, 5:11pm UTC](https://fortran-lang.discourse.group/t/how-to-get-a-list-of-module-procedures/3294/7 "2022-04-22T17:11:11Z")

</div>

The option given by @Beliavsky will detect the not listed procedures, assuming they are not called from other procedures inside the module.

---

<div class="post-metadata">

**Author:** ![NormanKirkby](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/normankirkby/32/1091_2.png) [@NormanKirkby](https://fortran-lang.discourse.group/u/NormanKirkby)\
**Post date:** [April 22, 2022, 5:43pm UTC](https://fortran-lang.discourse.group/t/how-to-get-a-list-of-module-procedures/3294/8 "2022-04-22T17:43:07Z")

</div>

My solution was to script an automatic way of generating explicit interfaces to “module procedures” but this can be alot of work, then put the implementations into one or more submodules.  
I think my script was based on one by Metcalf et al.  
Initial pain for long term gain.  
The stdlib goes further and uses the explicit interfaces as the sole point of declaration of even purely internal variables.  
More than happy to share my code if you think it might help.

---

<div class="post-metadata">

**Author:** ![FortranFan](https://avatars.discourse-cdn.com/v4/letter/f/96bed5/32.png) [@FortranFan](https://fortran-lang.discourse.group/u/FortranFan)\
**Post date:** [April 22, 2022, 8:17pm UTC](https://fortran-lang.discourse.group/t/how-to-get-a-list-of-module-procedures/3294/9 "2022-04-22T20:17:03Z")

</div>

> [@Rob777](#):
>
> What if a procedure is implemented in the contains section but I forgot to write it on the public declaration section? When the module contains hundred of procedure missing one is easy.
> 
> What I’m searching for is for the Compiler to throw an error if the procedure is in the contains section but not in the “list” section.

@Rob777 , you will know the Fortran standard itself does not provide an easy/convenient solution for what you seek. But you can look into utilities elsewhere that come close to what you are after or write one yourself.

With standard Fortran the approach suggested by @milancurcic upthread can be a good practice that you will find generally helpful.

Other than that, you can consider a long-winded approach as follows:

1. Separate out all your implementations from interfaces,
2. Then ensure your `MODULE`s only have `INTERFACE`s and stuff, but **no** `CONTAINS` section,
3. Employ `SUBMODULE`s for all your implementations i.e., the `CONTAINS` sections only appear in your `SUBMODULE`s. And importantly
4. Use the `MODULE` clause on all your subroutines and functions.

This way the interface construct becomes the **list** you want. Then if something is in your `CONTAINS` section but not in your “list”, the compiler will diagnose the omission. You can see this in the example below:

```fortran
module m
   interface !<-- Here's your "list"
      module subroutine sub()
      end subroutine 
   end interface
end module
submodule(m) sm
contains
   module subroutine sub() !<-- note the MODULE clause
      print *, "Hello World!"
   end subroutine
   module function fun() result(r) !<-- note the MODULE clause
      integer :: r
      r = 42
   end function 
end submodule 

```

> C:\Temp\>ifort /c /standard-semantics m.f90  
> Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.3.0 Build 20210609\_000000  
> Copyright (C) 1985-2021 Intel Corporation. All rights reserved.
> 
> m.f90(10): error #6115: A separate interface body must have been declared in the program unit or an ancestor of the program unit for the separate module procedure. [FUN]  
> module function fun() result(r)  
> …  
> compilation aborted for m.f90 (code 1)

So you can see the compiler detects and reports an error about the function `FUN` since it’s not on the “list” err… the interface block. This approach will be seen by many as verbose and boilerplate but that’s the pain you’ve to put up with for your gain.

---

<div class="post-metadata">

**Author:** ![Rob777](https://avatars.discourse-cdn.com/v4/letter/r/9e8a1a/32.png) [@Rob777](https://fortran-lang.discourse.group/u/Rob777)\
**Post date:** [April 22, 2022, 9:19pm UTC](https://fortran-lang.discourse.group/t/how-to-get-a-list-of-module-procedures/3294/10 "2022-04-22T21:19:08Z")

</div>

Thank you all for helping me.

@NormanKirkby thank you. I think sharing your code can be beneficial even if it’s not the exact solution to my original problem.

@FortranFan thank you. I think your solution is the only way to solve my problem using only standard Fortran.

I’m also thinking of writing a simple python script to check for procedures contained in the contains section but not listed as public or private.

Again Many thanks to everyone for your help.

---

<div class="post-metadata">

**Author:** ![urbanjost](https://avatars.discourse-cdn.com/v4/letter/u/0ea827/32.png) [@urbanjost](https://fortran-lang.discourse.group/u/urbanjost)\
**Post date:** [April 22, 2022, 11:16pm UTC](https://fortran-lang.discourse.group/t/how-to-get-a-list-of-module-procedures/3294/11 "2022-04-22T23:16:13Z")

</div>

sounds like you have your answer, but as a footnote there are commands that can extract symbol names from object files and executables that can be useful, as well as compilers with options to list procedure names as they are compiled and so on. Before modules and generic names were introduced Unix/GNU-Linux users could usually just  
enter

```bash
nm --defined-only *.o

```

there is an equivalent MSWIndows command but I do not remember it. The nm(1) command is still useful, but you have to know a little bit about how your compiler mangles procedure names contained in modules, and you often just get a list of all the specific procedures instead of a generic name (but if generic you already have a list in your global module area). So if it is just a one-time thing and you have the object or archive files for the routines you might just want to do an nm command, or look at what your compiler options provide or commands like objdump(1) or readelf(1); and even ld(1). I thought gfortran had an option to verbosely list the names as they were compiled; but perhaps not – I cannot find it. Some vendors supply commands to display information from mod files and/or have them hidden in their products that are primarily developer tools too; but that all gets very compiler-specific. But in some cases instead of writing or looking for parsers the nm(1) might be enough; and short of full language parsers just grepping for subroutine, function, and entry can tell you a lot; or a quick hack of f90split(1) might work; althought I do not know if the last version of f90split(1) knows about submodules.

---

<div class="post-metadata">

**Author:** ![NormanKirkby](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/normankirkby/32/1091_2.png) [@NormanKirkby](https://fortran-lang.discourse.group/u/NormanKirkby)\
**Post date:** [April 23, 2022, 7:25am UTC](https://fortran-lang.discourse.group/t/how-to-get-a-list-of-module-procedures/3294/12 "2022-04-23T07:25:11Z")

</div>

Please try this link

> **[MRC](https://www.dropbox.com/sh/9hbtwg2jwyb9t0e/AACGh3RVUVvdRdbzf-7MhkQja?dl=0)**
>
> Shared with Dropbox
