- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I need some help figuring out this new-fangled stuff.
Version 18.0.1.156 Build 20171018
I have tried to cut down the example as much as possible.
The commented-out assignment gives a syntax error. What is wrong? (The allocate works.)
And the program prints "Vehicle". I was expecting "Car". What is wrong there?
Thanks for the help.
module vehicle_module
implicit none
private
type, public :: vehicle_type
real :: weight
end type vehicle_type
type, public, extends(vehicle_type) :: car_type
logical :: is_a_taxi
end type car_type
end module vehicle_module
program test
use vehicle_module
implicit none
class(vehicle_type), dimension(:), allocatable :: aa
class(vehicle_type), allocatable :: v
!aa = [ vehicle_type :: ]
allocate (vehicle_type :: aa(0))
v = car_type(2000.0, .false.)
aa = [ aa, v ]
select type (temp_v=>aa(1))
type is (car_type)
write (unit=*, fmt="(a9)", advance="no") "Car:"
class default
write (unit=*, fmt="(a9)", advance="no") "Vehicle:"
end select
end program test
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Syntax error: This is a compiler bug - the syntax is correct (and creates an empty array of type vehicle_type). This error sounds very familiar - I thought it had been fixed a long time ago. Please report this through the Intel Online Service Center.
For your second question, different elements of an array can't have different types. In the array constructor [aa,v], each "ac-spec" must have the same declared type and type parameters (F08 C4103). They do here - vehicle_type - and that is the type of the constructor (4.8p2)
For the assignment to v in line 27, the standard requires that the variable be "type-compatible" with the expression. The standard says: "A polymorphic entity that is not an unlimited polymorphic entity is type compatible with entities of the same declared type or any of its extensions." (4.3.1.3p4) Since car_type is an extension of vehicle_type, this is ok. This assignment reallocates v to be of car_type. But from the previous paragraph, the array constructor ends up being vehicle_type and thus the SELECT TYPE reveals that.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The issue with the assignment statement is a compiler "bug" - the syntax for zero length array constructors for derived types is not yet supported (as of 18.0, I haven't tried the new beta yet but the ticket I raised is still open).
The dynamic type of an array constructor is the same as its declared type (F2008 4.8p4). In the absence of a `type-spec ::` thing out the front of the element sequence, the declared type of the array constructor is the same as the declared type of the element sequence expressions (which are constrained to all have the same declared type). In the example code, those elements have a declared type of vehicle.
Note that all elements of an array have the same dynamic type as the array itself - array elements may only differ in value, not type or type parameters. To store objects of differing dynamic type (or type parameters) in an array, the variation in type must occur at the level of a component of the elements in the array - you typically introduce a wrapper type with an allocatable component.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
So glad to see that Ian and I agree here!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I didn't get up early enough.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
FWIW, the empty array bug is still there in the first 2019 beta.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OK, I thought having the different types (of the class) in the same array was illegal (thanks Steve for the reference), so I first tried the wrapper scheme than IanH mentioned (see below). When it didn't work, I wandered into the weeds and produced the thing I posted above. Sorry, I should have posted the original (cut down version below). It works if the second assignment to vv is commented out. What is wrong with using a structure constructor? (This time I did look and couldn't see anything preventing this, but I don' find stuff as easily any more ... :-(). As is, the following prints "Vehicle:"
module vehicle_module
implicit none
private
type, public :: vehicle_type
real :: weight
end type vehicle_type
type, public, extends(vehicle_type) :: car_type
logical :: is_a_taxi
end type car_type
type, public :: vehicle_struct
class(vehicle_type), allocatable :: v
end type vehicle_struct
end module vehicle_module
program test
use vehicle_module
implicit none
class(vehicle_type), allocatable :: aa
type(vehicle_struct) :: vv
aa = car_type(2000.0, .false.)
vv%v = aa
vv = vehicle_struct(aa)
select type (temp_v=>vv%v)
type is (car_type)
write (unit=*, fmt="(a9)") "Car:"
class default
write (unit=*, fmt="(a9)") "Vehicle:"
end select
end program test
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Walt Brainerd wrote:
..the original (cut down version below). It works if the second assignment to vv is commented out. What is wrong with using a structure constructor? (This time I did look and couldn't see anything preventing this, but I don' find stuff as easily any more ... :-(). As is, the following prints "Vehicle:" ..
@Walt Brainerd,
Which version of Intel Fortran compiler are you using? With version 18.0 update 2, the code you posted prints "Car:" as you would expect it to. Note this is when the optimization is enabled, strangely with /Od compiler option to disable optimization, the program encounters a run-time exception at the second assignment, vv = vehicle_struct(aa). If that's what you're running into, you may want to report the problem at the Intel Online Service Center https://supporttickets.intel.com/?lang=en-US
Re: "What is wrong with using a structure constructor?" - nothing wrong with it as far as your code is concerned; reliable and robust compiler support for it is a different matter though!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
With two modifications to get around the bugs (in my version), my complete example works as expected.
As indicated in the first post, I have 18.1 and my license is expired :-(.
The strange thing is that when I created the example while authoring my book, I got it exactly right (with no compiler to check it).
I went astray revisiting it to see if it works and trying different ways of doing it.
Thank you for your comments that got me back on track.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page