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
653 조회수

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
502 조회수

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.

원본 게시물의 솔루션 보기

0 포인트
7 응답
andrew_4619
명예로운 기여자 III
624 조회수

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

0 포인트
jwmwalrus
새로운 기여자 I
590 조회수

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

0 포인트
Steve_Lionel
명예로운 기여자 III
583 조회수

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.

0 포인트
jwmwalrus
새로운 기여자 I
576 조회수

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?

0 포인트
andrew_4619
명예로운 기여자 III
535 조회수

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. 

0 포인트
jwmwalrus
새로운 기여자 I
523 조회수

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

 

0 포인트
Steve_Lionel
명예로운 기여자 III
503 조회수

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.

0 포인트
응답