- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I would like to put a question to those that work with the J3 and other committees that determine the standard.
Related to this thread:
https://software.intel.com/en-us/forums/intel-fortran-compiler-for-linux-and-mac-os-x/topic/593516
If I define a generic interface such as below:
module create_gen_int implicit none interface fun_gen real function fun_int(n) integer, intent(in) :: n end function fun_int !*** real function fun_real(x) real, intent(in) :: x end function fun_real end interface fun_gen end module create_gen_int
The code compiles without any problems.
However, if I move the interfaces to a separate block inside the same module and use "module procedure" in the generic, such as:
module create_gen_int2 implicit none interface real function fun_int(n) integer, intent(in) :: n end function fun_int !*** real function fun_real(x) real, intent(in) :: x end function fun_real end interface ! interface fun_gen module procedure fun_int module procedure fun_real end interface fun_gen end module create_gen_int2
This is not accepted by the standard. Ifort V. 16.0.3.210 generates the error:
create_gen_int2.f90(4): error #7950: Procedure name in MODULE PROCEDURE statement must be the name of accessible module procedure. [FUN_INT] real function fun_int(n)
Gfortran also complains with an error message.
OTOH, if I move the interfaces to a separate module, such as:
module create_ints implicit none interface real function fun_int(n) integer, intent(in) :: n end function fun_int !*** real function fun_real(x) real, intent(in) :: x end function fun_real end interface end module create_ints !********************************* module create_gen_int3 use create_ints implicit none interface fun_gen module procedure fun_int module procedure fun_real end interface fun_gen end module create_gen_int3
This is also not valid according to the standard. Ifort now issues the error:
create_gen_int3.f90(18): error #7950: Procedure name in MODULE PROCEDURE statement must be the name of accessible module procedure. [FUN_INT] module procedure fun_int
My question is, why don't the standard accept the last two examples? Since all of them do essentially the same thing?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In the cases where you are getting an error - the compiler wants the procedures to be module procedures ... because that's what the code specifies!
Just delete the module keyword...
module create_gen_int2 implicit none interface real function fun_int(n) integer, intent(in) :: n end function fun_int !*** real function fun_real(x) real, intent(in) :: x end function fun_real end interface ! interface fun_gen procedure fun_int !<--- No module keyword. procedure fun_real !<--- No module keyword. end interface fun_gen end module create_gen_int2
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Note the standard says in "C1507 (R1506) If MODULE appears in a procedure-stmt, each procedure-name in that statement shall denote a module procedure."
And module procedure is "3.112.4 module procedure: procedure defined by a module subprogram, or a procedure provided by an intrinsic module (R1408)"
Then for module subprogram it says "3.142.3 module subprogram subprogram that is contained in a module or submodule but is not an internal subprogram"
Note per your code snippet in the original post, subprograms such as fun_int and fun_real are not contained in any module or submodule, nor are they part of any intrinsic module. Hence the compiler error.
Now say you had code like so:
module some_implementation implicit none private public :: fun_int public :: fun_real contains real function fun_int(n) integer, intent(in) :: n ! actual code elided; arbitrary intruction below fun_int = real(n) end function fun_int real function fun_real(x) real, intent(in) :: x ! actual code elided; arbitrary intruction below fun_real = x + 1.0 end function fun_real end module module create_gen_int2 use some_implementation, only : fun_int, fun_real implicit none interface fun_gen module procedure fun_int module procedure fun_real end interface fun_gen end module create_gen_int2
Then the compilation will complete without errors on account of the processor being able to recognize the module subprograms of fun_int and fun_real from the module, some_implementation. But of course, a convenient coding practice is to define the generic interface in the same module as the implementation.
For situations where subprogram implementations need to be elsewhere, meaning not in the module where the generic interface is established, for whatever reason (large files, compilation cascades, etc.), it is worth considering the SUBMODULEs feature introduced starting with Fortran 2008 in one's code design:
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear FortranFan,
your code will certainly work because in the module some_implementation you're not only defining the interfaces to fun_int and fun_real but actually defining the procedures.
My question is why on my first example it is acceptable for the standard to define a generic interface that contains only the (explicit) interfaces of these routines in its body, whereas in the other two examples, although the very same interfaces are accessible to the module containing the generic, the standard considers the code wrong.
Perhaps I'm not reading with sufficient care the snippets of the standard you mentioned:
FortranFan wrote:
Note the standard says in "C1507 (R1506) If MODULE appears in a procedure-stmt, each procedure-name in that statement shall denote a module procedure."
And module procedure is "3.112.4 module procedure: procedure defined by a module subprogram, or a procedure provided by an intrinsic module (R1408)"
Then for module subprogram it says "3.142.3 module subprogram subprogram that is contained in a module or submodule but is not an internal subprogram"
But according to these regulations, even the first example should not be accepted by the standard, or am I wrong?
About your other suggestion:
FortranFan wrote:
For situations where subprogram implementations need to be elsewhere, meaning not in the module where the generic interface is established, for whatever reason (large files, compilation cascades, etc.), it is worth considering the SUBMODULEs feature introduced starting with Fortran 2008 in one's code design:
https://software.intel.com/en-us/blogs/2015/07/07/doctor-fortran-in-we-a...
I'm fully aware of SUBMODULES and use them whenever possible. I think they're a terrific (and necessary) improvement to the language.
Alas, for my specific application they won't work because I want to define a generic interface to C functions (via the iso_c_binding module). I wanted to create a specific module containing only the interfaces to the C functions and make them accessible to the module containing the generic, in a way similar to my third example. But it seems that the only way to implement this is doing something similar to my first example.
Anyway, thanks for the input.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
About my last comment:
rudi-gaelzer wrote:
Perhaps I'm not reading with sufficient care the snippets of the standard you mentioned:
...
But according to these regulations, even the first example should not be accepted by the standard, or am I wrong?
Scratch that. The first example does not contain the clause "module procedure" (duh...)...
The rest still stands.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
rudi-gaelzer wrote:
.. Alas, for my specific application they won't work because I want to define a generic interface to C functions (via the iso_c_binding module). I wanted to create a specific module containing only the interfaces to the C functions and make them accessible to the module containing the generic, ..
When I mentioned the scenario of "subprogram implementations need to be elsewhere" I was still considering code in "CONTAINS" section of some Fortran MODULE somewhere. But you are bringing up code defined by means other than Fortran i.e., C functions. Barring some "clever" programming which I stay from, generic interfaces are not possible unless you wrap those other procedures in Fortran, a seemingly wasted effort. Besides those C functions would be consumed in C calling programs explicitly, not generically. It might help to keep it that way in Fortran code also.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In the cases where you are getting an error - the compiler wants the procedures to be module procedures ... because that's what the code specifies!
Just delete the module keyword...
module create_gen_int2 implicit none interface real function fun_int(n) integer, intent(in) :: n end function fun_int !*** real function fun_real(x) real, intent(in) :: x end function fun_real end interface ! interface fun_gen procedure fun_int !<--- No module keyword. procedure fun_real !<--- No module keyword. end interface fun_gen end module create_gen_int2
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Indeed that seems to work.
Thanks for the tip.
ianh wrote:
Just delete the module keyword...
module create_gen_int2 implicit none interface real function fun_int(n) integer, intent(in) :: n end function fun_int !*** real function fun_real(x) real, intent(in) :: x end function fun_real end interface ! interface fun_gen procedure fun_int !<--- No module keyword. procedure fun_real !<--- No module keyword. end interface fun_gen end module create_gen_int2
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page