- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, I'm not sure if this is a bug or a feature of 16-upd3, but I have a problem applying a constructor for extended types as demonstrated by this code:
module foo_def
type, abstract :: foo
real x
end type foo
end module foo_def
module foo2_def
use foo_def
type, extends(foo) :: foo2
real y
end type foo2
interface foo
module procedure constructor
end interface
contains
function constructor(x, y) result(self)
real, intent(in) :: x, y
type(foo2) :: self
self % x = 2.3
self % y = 1.1
end function constructor
end module foo2_def
program test
use foo_def
use foo2_def
class(foo), allocatable :: f
allocate(foo2::f)
f = foo(x, y)
print*, f%x, f%y
end program test
I get the error codes:
1>F:\test.f90(29): error #6197: An assignment of different structure types is invalid. 1>F:\test.f90(29): error #8304: In an intrinsic assignment statement, variable shall not be polymorphic.1>F:\test.f90(30): error #6460: This is not a field name that is defined in the encompassing structure.
Based on above error messages I guess the compiler first deallocates f in line 29. Hence it is not of type foo2 anymore which leads to type mismatch regarding the foo2 result from the constructor. Is this a bug or a feature? Are assignments prohibited for allocated polymorphic objects? If I statically declare f to be of type(foo2) the code works as expected.
I know that constructors are not a part of Fortran but the trick of introducing a generic interface with the same name as the type name seems to be a standard trick working for all cases I have encountered except for allocated polymorphic variables. Any good work arounds?
Best regards,
Jens B. Helmers
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The real problem is that you're relying on a Fortran 2008 feature we don't yet support - intrinsic assignment to an allocatable polymorphic variable. This should be implemented in the next major release (second half of 2017.)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@Jens B. Helmers,
Look into:
- SOURCEd allocation facility introduced with Fortran 2003 and its caveats and advantages relative to what you're trying to do,
- whether it makes sense to have a generic interface with the same name as that of the abstract type whose extension type is the result of the underlying function of the interface,
- SELECT TYPE construct, for otherwise how the compiler can cast the polymorphic variable of an abstract type to access members of the dynamic type which could be any extension, and
- what is intended for the dummy arguments in the constructor function that are not utilized nor defined in the caller.
With a few changes along the above lines, you can do the following:
module foo_def
type, abstract :: foo
real x
end type foo
end module foo_def
module foo2_def
use foo_def
type, extends(foo) :: foo2
real y
end type foo2
interface foo2
module procedure constructor
end interface
contains
function constructor() result(self)
type(foo2) :: self
self % x = 2.3
self % y = 1.1
end function constructor
end module foo2_def
program test
use foo_def
use foo2_def
class(foo), allocatable :: f
allocate( f, source=foo2() )
select type ( f )
type is ( foo2 )
print*, f%x, f%y
end select
end program test
The above compiles with no errors or warnings: upon execution,
2.300000 1.100000
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page