PGF90-S-0142 error ... is not a member of this RECORD

The following code generates compilation errors:

module class_Circle
  implicit none
  private
  real :: pi = 3.1415926535897931d0 ! Class-wide private constant

  type, public :: Circle
     real :: radius
   contains
     procedure, public, pass :: area => circle_area
     procedure, public, pass :: print => circle_print
  end type Circle
contains
  function circle_area(this) result(area)
    class(Circle), intent(in) :: this
    real :: area
    area = pi * this%radius**2
  end function circle_area

  subroutine circle_print(this)
    class(Circle), intent(in) :: this
    real :: area
    area = this%area()  ! Call the type-bound function
    print *, 'Circle: r = ', this%radius, ' area = ', area
  end subroutine circle_print
end module class_Circle


program circle_test
  use class_Circle
  implicit none

  type(Circle) :: c     ! Declare a variable of type Circle.
  c = Circle(1.5)       ! Use the implicit constructor, radius = 1.5.
  call c%print          ! Call the type-bound subroutine
end program circle_test

The compiler output is:

PGF90-S-0142-area is not a member of this RECORD (testit.f95: 22)
PGF90-S-0075-Subscript, substring, or argument illegal in this context for area (testit.f95: 22)
0 inform, 0 warnings, 2 severes, 0 fatal for circle_print
PGF90-S-0155-Missing element in structure constructor- type circle (testit.f95: 33)
PGF90-S-0142-print is not a member of this RECORD (testit.f95: 34)
0 inform, 0 warnings, 2 severes, 0 fatal for circle_test

I’m using version 10.9 of the compiler.

I’m new to Fortran. What is my mistake?

Thanks.

There are a couple of things I see. First, you aren’t initializing c correctly. To set c’s radius you just need to do:

c%radius = 1.5

If you want to make this setting a call, or you want to keep radius private, then you’d need a circle_initialize subroutine that has a this%radius = radius sort of line in it and you call with call c%initialize(1.5) or some such.

Beyond that, I think it might be an issue of using names multiple times (lots of area’s) or the private/public bits. I slightly rewrote this to look like some OOF I’ve done (which is based on the style in Chapman) and came up with:

module class_Circle
  implicit none

  real, private :: pi = 3.1415926535897931d0 ! Class-wide private constant

  type, public :: Circle
     real :: radius
   contains
     procedure, public, pass :: area => circle_area
     procedure, public, pass :: print => circle_print
  end type Circle

  private :: circle_area, circle_print

contains
  real function circle_area(this)
    class(Circle) :: this
    circle_area = pi * this%radius**2
  end function circle_area

  subroutine circle_print(this)
    class(Circle) :: this
    print *, 'Circle: r = ', this%radius, ' area = ', this%area()
  end subroutine circle_print
end module class_Circle


program circle_test
  use class_Circle
  implicit none

  type(Circle) :: c     ! Declare a variable of type Circle.
  c%radius=1.5          ! Use the implicit constructor, radius = 1.5.
  call c%print()        ! Call the type-bound subroutine
end program circle_test

I decided to remove any confusion with lots of area’s by just returning circle_area in the function. And, also, added () after function/subroutine calls. I’ve always done this. I think it’s necessary, but the c%print doesn’t seem to need them. this%area does. Finally, I’m not sure you need intent(in) with the class calls. I’ve never seen those.

I’m not sure this is elegant, but it seems to work. Maybe some real OO gurus can pipe up with better OO code than this.

Hope this helps,
Matt

Thanks much for taking the time to rework my example.

Based on my reading of Fortran 95/2003 Explained (Metcalf,Reid, Cohen),
my original example should have worked, but your modifications allow me to move forward.

Disturbingly, trying to initialize a circle instance as follows:

c = Circle(radius=1.5)

causes compiler v10.9 to abort (as in crash).

Hi j vickroy,

The code is fine. We’re in the process of adding F2003 support to the compilers and 10.9 is close but not all the way there. Your code will compile with the 11.0 compilers due out in a few weeks.

Best Regards,
Mat