Undefined symbols for deferred bindings

View: New views
3 Messages — Rating Filter:   Alert me  

Undefined symbols for deferred bindings

by Rouson, Damian :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

The code below compiles correctly (hooray!), but the linker can't find the
symbols related to the deferred bindings.  It's possible there's a problem
in my link line, so you might jump straight to the bottom.  Otherwise, foo
defines an abstract type (as in my previous posting); bar extends foo and
overrides foo's deferred bindings; and main declares a bar object and passes
it to the "rescale" procedure inside foo_module.

Damian

$ cat foo.f90
module foo_module
  implicit none
  private
  public :: foo,rescale

  type ,abstract :: foo
  contains
    procedure(times_interface) ,deferred :: times
    procedure(assign_interface) ,deferred :: assign
    generic :: operator(*) => times
    generic :: assignment(=) => assign
  end type

  abstract interface
    function times_interface(this,factor) result(product)
      import :: foo
      class(foo) ,intent(in) :: this
      class(foo) ,allocatable :: product
      real, intent(in) :: factor
    end function
    subroutine assign_interface(lhs,rhs)
      import :: foo
      class(foo) ,intent(inout) :: lhs
      class(foo) ,intent(in) :: rhs
    end subroutine
  end interface

contains
  subroutine rescale(this,scale)
    class(foo) ,intent(inout) :: this
    real, intent(in) :: scale
    this = this*scale
  end subroutine
end module
$
$ cat bar.f90
module bar_module
  use foo_module ,only : foo
  implicit none
  private
  public :: bar

  type ,extends(foo) :: bar
    private
    real :: x=1.
  contains
    procedure :: times => times_bar
    procedure :: assign => assign_bar
  end type

contains
  subroutine assign_bar(lhs,rhs)
    class(bar) ,intent(inout) :: lhs
    class(foo) ,intent(in) :: rhs
    select type(rhs)
      type is (bar)
        lhs%x = rhs%x
    end select
  end subroutine
  function times_bar(this,factor) result(product)
    class(bar) ,intent(in) :: this
    real, intent(in) :: factor
    class(foo), allocatable :: product
    select type(this)
      type is (bar)
        allocate(product,source=this)
        select type(product)
          type is(bar)
            product%x = this%x*factor
        end select
    end select
  end function
end module
$
$ cat main.f90
program main
  use foo_module ,only : foo,rescale
  use bar_module ,only : bar
  implicit none
  type(bar) :: unit
  call rescale(unit,3.141592654)
end program
$
$ make
gfortran -c foo.f90
gfortran -c bar.f90
gfortran -c main.f90
gfortran main.o foo.o bar.o -o foobar
Undefined symbols:
  "_assign_interface_", referenced from:
      ___foo_module_MOD_rescale in foo.o
  "_times_interface_", referenced from:
      ___foo_module_MOD_rescale in foo.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
make: *** [foobar] Error 1



Re: Undefined symbols for deferred bindings

by Janus Weil-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Damian,

> The code below compiles correctly (hooray!), but the linker can't find the
> symbols related to the deferred bindings.  It's possible there's a problem
> in my link line, so you might jump straight to the bottom.  Otherwise, foo
> defines an abstract type (as in my previous posting); bar extends foo and
> overrides foo's deferred bindings; and main declares a bar object and passes
> it to the "rescale" procedure inside foo_module.

sorry for the late answer. I don't think there's a problem in your
link line. Rather I would say deffered TBPs are just an unimplemented
feature for now (if I'm not mistaken). Hopefully that should change
once Paul's new patch for dynamic dispatch has landed on the branch.


> Undefined symbols:
>  "_assign_interface_", referenced from:
>      ___foo_module_MOD_rescale in foo.o
>  "_times_interface_", referenced from:
>      ___foo_module_MOD_rescale in foo.o
> ld: symbol(s) not found

Trying to explain these error messages: We had support for ('static')
TBPs before we had polymorphism. In this old implementation, calling a
TBP would be translated statically to a call of the bound procedure.
Since for deferred TBPs, we have nothing that is bound to it, we just
generate a call to the interface symbol (so that at least the call can
be checked for correctness etc). But, since this is just an interface,
not a real procedure, it does not actually exist and linking fails. At
least that is what I think is happening. Paul or Daniel may be able to
tell you more about this.

Cheers,
Janus

Re: Undefined symbols for deferred bindings

by Rouson, Damian :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

(This is a resend.  I keep forgetting to turn off HTML formatting)

Janus,

Thanks for the clear explanation.  I¹ll resume testing after Paul¹s patch
lands on the branch.

Damian


On 11/11/09 5:08 AM, "Janus Weil" <janus@...> wrote:

> Hi Damian,
>
>> The code below compiles correctly (hooray!), but the linker can't find the
>> symbols related to the deferred bindings.  It's possible there's a problem
>> in my link line, so you might jump straight to the bottom.  Otherwise, foo
>> defines an abstract type (as in my previous posting); bar extends foo and
>> overrides foo's deferred bindings; and main declares a bar object and passes
>> it to the "rescale" procedure inside foo_module.
>
> sorry for the late answer. I don't think there's a problem in your
> link line. Rather I would say deffered TBPs are just an unimplemented
> feature for now (if I'm not mistaken). Hopefully that should change
> once Paul's new patch for dynamic dispatch has landed on the branch.
>
>
>> Undefined symbols:
>>  "_assign_interface_", referenced from:
>>      ___foo_module_MOD_rescale in foo.o
>>  "_times_interface_", referenced from:
>>      ___foo_module_MOD_rescale in foo.o
>> ld: symbol(s) not found
>
> Trying to explain these error messages: We had support for ('static')
> TBPs before we had polymorphism. In this old implementation, calling a
> TBP would be translated statically to a call of the bound procedure.
> Since for deferred TBPs, we have nothing that is bound to it, we just
> generate a call to the interface symbol (so that at least the call can
> be checked for correctness etc). But, since this is just an interface,
> not a real procedure, it does not actually exist and linking fails. At
> least that is what I think is happening. Paul or Daniel may be able to
> tell you more about this.
>
> Cheers,
> Janus
>
>