Substituindo função privada em módulo diferente

Aug 29 2020

Se um procedimento vinculado ao tipo que é privado em um módulo foofor substituído (ou tentar ser substituído) por um tipo em um segundo módulo bar, como isso será resolvido? Existe alguma especificação no padrão? Considerando que o código de exemplo a seguir, dependendo do compilador, imprime FOO (intel fortan 19.1.1) ou BAR (gfortran 7.5, talvez uma versão mais recente dê resultados diferentes?), Me pergunto qual é a correta.

module foo

type :: foo_t
contains
    procedure, private :: foobar
    procedure :: exec
end type foo_t

contains

    subroutine exec(obj)
        class(foo_t) :: obj
        call obj%foobar()
    end subroutine exec

    subroutine foobar(this)
        class(foo_t) :: this
        print *, "FOO"
    end subroutine foobar
end module foo

module bar
    use foo

    type, extends(foo_t) :: bar_t
    contains
        procedure :: foobar => impl
    end type bar_t

contains

    subroutine impl(this)
        class(bar_t) :: this
        print *, "BAR"
    end subroutine impl
end module bar

program test
    use foo
    use bar

    class(foo_t), allocatable :: inst
    allocate( bar_t :: inst)
    call inst%exec()
end program test

Além disso, é possível estender um tipo abstrato com um método adiado privado em um módulo diferente, como seria o caso no exemplo se foobarfosse adiado (que só compila com o compilador gfortran mencionado acima e então produz o resultado esperado, mas o questão é se este também é o comportamento correto)?

Respostas

4 IanH Aug 29 2020 at 09:18

O resultado correto é FOO.

Este é um bug conhecido no gfortran (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47805)

Uma ligação privada não está acessível em outro módulo. Como a associação privada não está acessível no módulo bar, ela não é substituída (F2018 7.5.7.3p1). A definição de ligação em bar_t não está relacionada à ligação em foo_t.

(Um tipo abstrato com uma ligação privada adiada não pode ser usado fora do módulo que o define. Veja a interpretação F08 / 0052 para mais detalhes.)