Andres Valdez
Andres Valdez

Reputation: 164

OOP and Fortran90

Hello I am trying to learn Object Oriented Programming using Fortran (all my codes are written in Fortran 90), I partially know C++ but I want to carry on using Fortran.

In Fortran you make classes employing modules. I am facing compiling errors when writing the integer, parameter :: dp = selected_real_kind(15,307) statement. Here goes my academic code. Its a short code that uses Abstract classes

module class_Rectangle
  implicit none
  integer, parameter :: dp = selected_real_kind(15,307)
  type Rectangle
     real(dp) :: a,b
  end type Rectangle
contains
  subroutine area_rectangle(area,info)
    implicit none
    real(dp), intent(out) :: area
    type(Rectangle), intent(in) ::  info

    area = info%a * info%b

  end subroutine area_rectangle
end module class_Rectangle

program Main
  use class_Rectangle
  use class_Circle
  implicit none

  integer, parameter :: dp = selected_real_kind(15,307)

  interface compute_area
     module procedure area_rectangle, area_circle
  end interface compute_area

  type(Rectangle) :: geoA
  type(Circle) :: geoB
  real(dp) :: area

  geoA = Rectangle(2.0d0,4.0d0)
  call area_rectangle(area,geoA)
  write(*,*) 'Rectangle area:', area
  geoB = Circle(1.0d0)
  call area_circle(area,geoB)
  write(*,*) 'Circle area:',area

end program Main

The message that the compiler returns me is the following:

integer, parameter :: dp = selected_real_kind(15,307)
                          1

Error: Name 'dp' at (1) is an ambiguous reference to 'dp' from module 'class_rectangle' Main.f90:81.13:

  real(dp) :: area
         1

Error: Name 'dp' at (1) is an ambiguous reference to 'dp' from module 'class_rectangle' Main.f90:84.30:

Any hint or advice is welcome.

Upvotes: 2

Views: 435

Answers (3)

Scientist
Scientist

Reputation: 1835

Always try to use USE statement with ONLY. If you do so, you will not encounter the ambiguity error you get. In addition, you will know exactly what is being used in your code from each module, just by a quick look at the top lines of your code. Therefore, your main program header could look like this:

program Main

use class_Rectangle, only: Rectangle, area_rectangle
use class_Circle, only: Circle, area_circle
implicit none


integer, parameter :: dp = selected_real_kind(15,307)

interface compute_area
        module procedure area_rectangle, area_circle
end interface

type(Rectangle) :: geoA
type(Circle) :: geoB
real(dp) :: area

geoA = Rectangle(2.0d0,4.0d0)
call area_rectangle(area,geoA)
write(*,*) 'Rectangle area:', area
geoB = Circle(1.0d0)
call area_circle(area,geoB)
write(*,*) 'Circle area:',area

end program Main

For a good tutorial on OOP programming in Fortran with some good examples, see the book "Modern Fortran Explained" by Metcalf et al.

Upvotes: 1

Michael
Michael

Reputation: 42

Just omit: integer, parameter :: dp = selected_real_kind(15,307) in the main program! By USEing class_Rectangle the main program it shares this variable with the module (except you declare it private, which is not what you want here I guess).

Upvotes: 0

ptb
ptb

Reputation: 2148

Depending on your compiler, you should get pretty helpful messages

module a
end module a

program b
    implicit none
    use a
end program b

And compile:

$ gfortran mod_test.F90
mod_test.F90:6:9:

     implicit none
                 2
     use a
         1
Error: USE statement at (1) cannot follow IMPLICIT NONE statement at (2)

Upvotes: 0

Related Questions