Jeremy Kozdon
Jeremy Kozdon

Reputation: 141

fortran extended types over different modules

With extended types in Fortran should a private component by visible to a type extension in a different module.

With both gcc4.7 and ifort the following code results in a error since bName is in both the initial type and the extension. But since it's private, it isn't accesible in the extension in a different module, i.e., if you comment out bName in the bar_type you will get an error that it's private.

module foo
  type :: foo_type
    character(256),private :: bName = "foo"
  contains
    procedure :: pName => pName
  end type
contains
  subroutine pName(this)
    class(foo_type), intent(in) :: this
    print*,trim(this%bName)
  end subroutine
end module

module bar
  use foo, only : foo_type
  type,extends(foo_type) :: bar_type
    character(256),private :: bName = "bar"
  contains
    procedure :: pName => pName
  end type
contains

  subroutine pName(this)
    class(bar_type), intent(in) :: this
    print*,this%bName
  end subroutine
end module


program test
  use foo, only : foo_type
  use bar, only : bar_type
  type(foo_type) :: foo_inst
  type(bar_type) :: bar_inst

  call foo_inst%pName()
  call bar_inst%pName()
end program

If bar_type was contained in the same module as foo_type, then bName would be accessible from bar_type, i.e., the following code will compile

module foo
  type :: foo_type
    character(256),private :: bName = "foo"
  contains
    procedure :: pName => pName
  end type

  type, extends(foo_type) :: baz_type
  contains
    procedure :: pName => pName_baz
  end type
contains
  subroutine pName_baz(this)
    class(baz_type), intent(in) :: this
    print*,trim(this%bName)
  end subroutine

  subroutine pName(this)
    class(foo_type), intent(in) :: this
    print*,trim(this%bName)
  end subroutine
end module

program test
  use foo, only : foo_type,baz_type
  type(foo_type) :: foo_inst
  type(baz_type) :: baz_inst

  call foo_inst%pName()
  call baz_inst%pName()
end program

Been having a hard time parsing the standards to know what should happen in the first example.

Upvotes: 4

Views: 585

Answers (1)

eriktous
eriktous

Reputation: 6649

I believe the first example is not standard-conforming.

Even though the private attribute makes the component bName inaccessible outside module foo, it is still inherited by bar_type (perhaps rather pointless, because nothing can be done with it, but that's not the issue) -- see Note 4.51 in f2003:

Inaccessible components and bindings of the parent type are also inherited, but they remain inaccessible in the extended type. Inaccessible entities occur if the type being extended is accessed via use association and has a private entity.

So bar_type has an inherited component with the name bName, which makes it an error to add another component by that name (see paragraph 16.2 for scope and name rules).

Upvotes: 2

Related Questions