hidden text to trigger early load of fonts ПродукцияПродукцияПродукцияПродукция Các sản phẩmCác sản phẩmCác sản phẩmCác sản phẩm المنتجاتالمنتجاتالمنتجاتالمنتجات מוצריםמוצריםמוצריםמוצרים
Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28988 ディスカッション

Binding label restriction for submodule procedures

jwmwalrus
新規コントリビューター I
656件の閲覧回数

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.

0 件の賞賛
1 解決策
Steve_Lionel
名誉コントリビューター III
506件の閲覧回数

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.

元の投稿で解決策を見る

7 返答(返信)
andrew_4619
名誉コントリビューター III
628件の閲覧回数

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.....

jwmwalrus
新規コントリビューター I
593件の閲覧回数

@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.

Steve_Lionel
名誉コントリビューター III
586件の閲覧回数

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.

jwmwalrus
新規コントリビューター I
579件の閲覧回数

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?

andrew_4619
名誉コントリビューター III
538件の閲覧回数

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. 

jwmwalrus
新規コントリビューター I
526件の閲覧回数

@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.

 

Steve_Lionel
名誉コントリビューター III
507件の閲覧回数

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.

返信