Reputation: 164
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
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
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
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