- 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