- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
(See the ~30 line reproducer below/attached. I'm using `ifort 2021.13.1 20240703` and `ifx 2024.2.1 20240711`.)
For a `module function` with the interface in the parent module, and implementation in the submodule, it's often nice to have the declaration and definition lines match [ie `real module function pi() result(p)`]. It's also nice to use `implicit none`.
This works with `real`, but with eg `real(8)` the compiler complains in the submodule that the `result` variable lacks a type.
The workaround we're using for now is to delete the `result(...)` portion of the declaration.
Has anyone else seen this?
I'm not sure if it's a bug exactly, but the error message was not helpful, as there is nothing you can do at the definition site to make this work (that I found).
! Valid combinations for ifort, ifx
! (1) and (4). Note these match exactly
! (3) and (5). Note (3) is just (5) but without a result(...) declaration
! Gfortran additionally works with
! (2) and (5). Note these match exactly
module the_interface
implicit none
interface
real module function pi() result(p) ! (1)
!real(8) module function pi() result(p) ! (2)
!real(8) module function pi() ! (3)
end function pi
end interface
end module the_interface
submodule (the_interface) the_impl
implicit none
contains
real module function pi() result(p) ! (4)
!real(8) module function pi() result(p) ! (5)
p = 22.0 / 7
end function pi
end submodule the_impl
program main
use the_interface
implicit none
print *, "pi is ", pi()
end program main
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Well I agree that it is a bug. There were numerous similar bugs when submodules were first introduced but it seem there is one more...
It shows the same behaviour in IFX 2025.3. Another (and IMO better workaround would be:
module the_interface
implicit none
interface
module function pi() result(p)
real(8) :: p
end function pi
end interface
end module the_interface
submodule (the_interface) the_impl
implicit none
contains
module function pi() result(p)
real(8) :: p
p = 22.0 / 7
end function pi
end submodule the_impl
program main
use the_interface
implicit none
print *, "pi is ", pi()
end program mainThat is my personal preference also as I think a type declaration as a function pre-fix is anomalous to the general layout of modern Fortran.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If I were doing that I would also avoid real(8) in a declaration in favour of either real(dp) where dp had been defined as selected_real_kind(15) or real(kind(1d0), and even more so I wouldn't define a constant called pi as 22.0/7, which is a default real wrong value: 22d0/7 would at least get a double precision value. But a value correct in double precision is acos(-1.0_dp).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for taking the time to reply, JFH.
Perhaps I should have made it clearer that this is a small digestible reproducer, and is meant to demonstrate the mechanisms at work with as little indirection or complication as possible.
Naturally, in our actual code base we use `selected_real_kind`. Pi has nothing to do with anything, I just as easily could have had the function return `1.0`. But I'm glad you clarified that `22/7` is not precisely pi, as that could have been very confusing for some readers.
Cheers
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for checking with your ifx version too. Yeah, my team is thinking about a refactor to inside-body type declarations everywhere. The context for this is I'm ensuring `implicit none` everywhere in a massive older codebase, and that turned out to break some functions, but only ones with parameterized return types out front, and `result(...)` vars. Very niche I expect.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have a large number of functions in submodules that use result. It just happens I always use the internal declaration. Some years back I wrote a code to extract interfaces so a large number of external subroutines could go in submodules. I found the external form of function declaration a real pain as it creates so many potential variations. At that point they got fully eliminated which was not a big job and was quicker than making the extractor fully featured! IMO when they introduced submodules module function should have been restricted to internal declaration only.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page