- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi.
The following code
module mod1
use ISO_C_BINDING
implicit none
private
interface
module subroutine dummy()
end subroutine
end interface
end module
submodule (mod1) sm_callback
implicit none
contains
module procedure dummy
end procedure
function callback(arg) bind(C) result(res)
type(C_PTR) :: res
type(C_PTR), value :: arg
res = C_NULL_PTR
end function
end submodule
Fails to compile with
$ ifx -V -c /media/vmshare/submod-callback.f90
Intel(R) Fortran Compiler for applications running on Intel(R) 64, Version 2025.0.1 Build 20241113
Copyright (C) 1985-2024 Intel Corporation. All rights reserved.
Intel(R) Fortran 25.0-1205.1
/media/vmshare/submod-callback.f90(17): error #6117: A module procedure in a submodule that is not a separate module procedure cannot have a binding label.
function callback(arg) bind(C) result(res)
---------------------------^
compilation aborted for /media/vmshare/submod-callback.f90 (code 1)
I know that the solutions is to just have an interface block for the "callback" function in the parent module, but why is that necessary?
Btw, gfortran 14 compiles the code without issue.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The only thing that occurs to me, is that there's probably another constraint that guarantees that the procedure name is not mangled only if its interface is declared in the parent module.
I think this is it.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Well without the interface it has no external visibility and the whole point of bind(C) is to allow it to be called from C so to me that is a sound call by the compiler. As to what the standard chapter and verse says I have not looked.....
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@andrew_4619 wrote:Well without the interface it has no external visibility and the whole point of bind(C) is to allow it to be called from C so to me that is a sound call by the compiler. As to what the standard chapter and verse says I have not looked.....
Isn't the visibility really a thing of the linker? Having the interface block doesn't seem to add much.
I have code that does this
module mod1
use ISO_C_BINDING
implicit none
private
interface
module subroutine dummy()
end subroutine
end interface
end module
submodule (mod1) sm_callback
implicit none
contains
module procedure dummy
! invoke C function here, passing callback as an arg.
contains
function callback(arg) bind(C) result(res)
type(C_PTR) :: res
type(C_PTR), value :: arg
res = C_NULL_PTR
end function
end procedure
end submodule
That is, the callback being passed is a contained procedure, and it works just fine. It was only when I tried to re-use that same callback from multiple places in the submodule, that the error was thrown.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
C1807 A procedure defined in a submodule shall not have a binding label unless its interface is declared in the ancestor module.
NAG Fortran also doesn't like your code either. I played with this for a bit but couldn't figure out how to satisfy the standard - perhaps I'm just tired.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for the pointer to the standard.
I still fail to see how passing a contained procedure is okay, but a non-contained one requires an interface in the parent module.
Do you mind expanding on the reasoning behind that constraint?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It isn't OK in my opinion. As to "Isn't the visibility really a thing of the linker?" , well no, I want procedures in a sub-module to have no external visibility, they are private and if they were not so it invalidates the purpose of a sub-module which is to separate interface and implementation to minimise build cascades.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@andrew_4619 wrote:It isn't OK in my opinion. As to "Isn't the visibility really a thing of the linker?" , well no, I want procedures in a sub-module to have no external visibility, they are private and if they were not so it invalidates the purpose of a sub-module which is to separate interface and implementation to minimise build cascades.
We're talking about C binding, so C doesn't really care about Fortran's PUBLIC|PRIVATE attributes. All that matters is whether the procedure name in the object file is either global (i.e., external) or local to the object. Since submodules can be in separate files (and might therefore be associated to separate object files), their procedure names have to be global.
(In fact, gfortran has a bug related submodules not seeing the parent module's private definitions because the generated object file for the module considers them local.)
The only thing that occurs to me, is that there's probably another constraint that guarantees that the procedure name is not mangled only if its interface is declared in the parent module.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The only thing that occurs to me, is that there's probably another constraint that guarantees that the procedure name is not mangled only if its interface is declared in the parent module.
I think this is it.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page