Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Problem with structure constructor

MR
Beginner
266 Views

ifort produces an error compiling the following code:

module m
 implicit none

 type, abstract :: c_a
 end type c_a

 type, extends(c_a), abstract :: c_b
 !type, abstract :: c_b ! removing the ancestor solves the problem
  real, pointer :: x => null()
 end type c_b

 type, extends(c_b) :: t_c
  logical :: l
 end type t_c

end module m

program p
 use m
 implicit none

 real, target :: r
 ! renaming/removing the variable x solves the problem
 type(t_c),  parameter   :: x = t_c( l=.false. )
 class(c_b), allocatable :: y

  allocate( y , source=t_c( l=.true. , x=r ) )

  select type(y); type is(t_c)
  write(*,*) "y%l = ", y%l
  end select

end program p

$ ifort test.f90 -o test
test.f90(27): error #6593: The number of expressions in a structure constructor differs from the number of components of the derived type.   [C_B]
  allocate( y , source=t_c( l=.true. , x=r ) )

I am using ifort Version 16.0.2.181 Build 20160204

The code is correct as far as I can tell, and gfortran compiles it.

Also, notice that altering the code as indicated in the comments makes the problem disappear - or at least the symptoms.

Marco

0 Kudos
3 Replies
Steven_L_Intel1
Employee
266 Views

Thanks - I found also that renaming the component x makes the error go away. Escalated to development as issue DPD200408385. I've seen weird errors show up in ALLOCATE(SOURCE=) that don't appear elsewhere (I can add the same constructor later in the program and it's fine), so this looks to be another case. I will update this thread when there is news.

0 Kudos
MR
Beginner
266 Views

Steve, thank you for checking and reporting!

Since you mention source allocation, I just add that I see the same problem also with the following version (the module m is the same as before, the only difference is in the program p)

module m
 implicit none

 type, abstract :: c_a
 end type c_a

 type, extends(c_a), abstract :: c_b
 !type, abstract :: c_b ! removing the ancestor solves the problem
  real, pointer :: x => null()
 end type c_b

 type, extends(c_b) :: t_c
  logical :: l
 end type t_c

end module m

program p
 use m
 implicit none

 real, target :: r
 ! renaming/removing the variable x solves the problem
 type(t_c), parameter :: x = t_c( l=.false. )
 type(t_c) :: y

  y = t_c( l=.true. , x=r )

  write(*,*) "y%l = ", y%l

end program p

Strange, indeed!

Marco

0 Kudos
Steven_L_Intel1
Employee
266 Views

That's interesting - I had tried something similar as a modification of your original example by putting an assignment to y inside the SELECT TYPE. Thanks, I'll add this test case as well.

0 Kudos
Reply