Pergunta

I'm trying to debug some code in which members of a user defined object mysteriously change addresses, and while doing that I realized user defined objects do that as well. Here's a small example of querying object address from function that created it and then from its member function:

  module foo_module

    type foo_type
      contains
        procedure :: foo
    end type foo_type

    contains

      subroutine foo(this)
        class(foo_type) :: this
        print *, 'Inside foo this is', loc(this)
      end subroutine foo

  end module foo_module


  program trial

    use foo_module
    type(foo_type) :: object

    print *, 'Object address', loc(object)
    call object%foo()

  end program trial

A sample output I get is:

Object address            4452052800
Inside foo this is       140734643354880

Why am I getting two different addresses for the same object? Am I doing something wrong? Or is there something with LOC that comes into play I don't understand?

I'm using ifort under osx.

Foi útil?

Solução

LOC is an extension. Its behaviour is as specified by the compiler vendor.

What the behaviour intended by the vendor here isn't clear, but the difference that you are seeing is that in the main program you get the integer equivalent of the memory address of the non-polymorphic object (what you probably expect), while in the subroutine you get the integer equivalent of the memory address of the polymorphic descriptor for the object (maybe what you want, maybe not).

Using TRANSFER(C_LOC(xxx), 0_C_INTPTR_T) is a more portable way of getting the integer representation of the address of an object (where the C_* things are from the ISO_C_BINDING intrinsic module). C_LOC requires that its argument have the TARGET attribute and be non-polymorphic (use SELECT TYPE).

I'd recommend asking on the relevant Intel Forum if you want further clarification on the intended behaviour of the LOC extension.

Outras dicas

I reported the bug to the developers our internal issue ID is DPD200253159. I found that the C_LOC function from ISO_C_BINDING works. For example:

  subroutine foo(this)
    use, intrinsic :: iso_c_binding
    class(foo_type) :: this
    print *, 'Inside foo this is', transfer(c_loc(this),0_C_INTPTR_T)
  end subroutine foo
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top