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

Nested allocatable type with allocatable components

marinoni__andrea_mas
2,294 Views

Hi all,

I am trying to use an allocatable type whose component is a type with an allocatable component. I report an example of the issue:

module module_try 
    implicit none
    
    type A_type
        character(len=5) :: A_char      
        double precision, dimension(:), allocatable :: A_double
    endtype A_type
    
    type B_type
        character(len=5) :: B_char
        type(A_type)     :: A
    end type B_type
    
    type(B_type), dimension(:), allocatable :: B
    
contains
    
    subroutine try
        allocate(B(2))              ! no errors
        allocate(B%A%A_double(3))   ! no errors
        B(1)%A%A_double(:) = 1.d0   ! no errros
        B(2)%A%A_double(:) = 2.d0   ! no errors
        print*, 'Hello World_1'
        print*, B(1)%A%A_double(:)
        print*, 'Hello World_2'
        print*, B(2)%A%A_double(:)  ! nothing printed
        print*, 'Hello World_3' 
        !B(2)%A%A_double(1) = 2.d0   ! gives error
    end subroutine try

end module module_try

The problem is that the allocation of the variables seems to work but during debugging the debugger shows 'Undefined pointer/array' when watching the nested allocated types and printing the variables does not correspond to the code instructions.
I attached the .f90 file.

0 Kudos
1 Solution
jimdempseyatthecove
Honored Contributor III
2,294 Views

Here is a complete reproducer for you to submit.

module module_try 
    implicit none
    
    type A_type
        character(len=15) :: A_char      
        double precision, dimension(:), allocatable :: A_double
    endtype A_type
    
    type B_type
        character(len=15) :: B_char
        type(A_type)     :: A
    end type B_type
    
    type(B_type), dimension(:), allocatable :: B
    
contains
    subroutine peek_A(A)
        type(A_type) :: A
        ! when needing to debug, break on following line
        if(.not. allocated(A%A_double) )print *,"Bug"
    end subroutine peek_A
    subroutine try
        allocate(B(2))               ! no errors
        B(1)%B_char = 'B(1)'
        B(2)%B_char = 'B(2)'
        !allocate(B%A%A_double(3))   ! wrong allocation
        print *,allocated(B(1)%A%A_double)
        allocate(B(1)%A%A_double(3)) ! no errors, correct allocation
        B(1)%A%A_char = 'B(1)%A'        ! *** B(1)%A%A_char Visible in Debugger
        B(1)%A%A_double(1) = 123.456    ! *** B(1)%A%A_double .NOT. Visible in Debugger
! ********** VS integration error *********
! unable to view B(1)%A%A_double in debugger
! Microsoft Visual Studio Professional 2013
! Version 12.0.40629.00 Update 5
! Intel® Parallel Studio XE 2019 Update 3 Composer Edition for Fortran Windows*   Package ID: w_comp_lib_2019.3.203
        call peek_A(B(1)%A)             ! For debugging you can insert something like this
        print *,allocated(B(1)%A%A_double)
        print *,size(B(1)%A%A_double)
        allocate(B(2)%A%A_double(3)) ! no errors, correct allocation
        B(1)%A%A_double(:) = 1.d0    ! no errros
        B(2)%A%A_double(:) = 2.d0    ! no errors
        print*, 'Hello World_1'
        print*, B(1)%A%A_double(:)
        print*, 'Hello World_2'
        print*, B(2)%A%A_double(:)
        print*, 'Hello World_3' 
        !B(2)%A%A_double(1) = 2.d0
    end subroutine try

end module module_try

program Nested
    use module_try
    call try
end program Nested

Note to Intel, the nested allocatable array is not visible in both Win32 and x64 Debug builds.

Jim Dempsey

View solution in original post

0 Kudos
13 Replies
FortranFan
Honored Contributor II
2,294 Views

You should follow up with Intel Support about this, a good compiler system will issue a diagnostic re: line 20 in the code you show which is not allowed in the language.  It has to be like so:

    subroutine try
        allocate(B(2))              ! no errors
        allocate(B(1)%A%A_double(3))   ! no errors
        allocate(B(2)%A%A_double(3))   ! no errors
        B(1)%A%A_double(:) = 1.d0   ! no errros
        B(2)%A%A_double(:) = 2.d0   ! no errors
        print*, 'Hello World_1'
        print*, B(1)%A%A_double(:)
        print*, 'Hello World_2'
        print*, B(2)%A%A_double(:)  ! nothing printed
        print*, 'Hello World_3'
        !B(2)%A%A_double(1) = 2.d0   ! gives error
    end subroutine try

 

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,294 Views

Good reproducer. My Comments:

module module_try 
    implicit none
    
    type A_type
        character(len=5) :: A_char      
        double precision, dimension(:), allocatable :: A_double
    endtype A_type
    
    type B_type
        character(len=5) :: B_char
        type(A_type)     :: A
    end type B_type
    
    type(B_type), dimension(:), allocatable :: B
    
contains
    
    subroutine try
        allocate(B(2))              ! no errors *** valid statement, good result
        allocate(B%A%A_double(3))   ! no errors *** invalid statement, bad result
*** should have been:
***  allocate(B(1)%A%A_double(3))
***  allocate(B(2)%A%A_double(3))   
        B(1)%A%A_double(:) = 1.d0   ! no errros *** see below
        B(2)%A%A_double(:) = 2.d0   ! no errors *** see below
*** Had the correct  allocate(B(1)%A%A_double(3))... occurred, then no error is OK
*** Had incorrect allocate(B%A%A_double(3)) NOT occurred and thus A_double not be allocated
*** then (I could not see this in the F2003 spec, Steve help please)
*** it appears undefined (F2003) as to what happens with assignment of scalar to
*** unallocated allocatable array as there is no shape. ?Error or NO-OP?
        print*, 'Hello World_1'
        print*, B(1)%A%A_double(:)
        print*, 'Hello World_2'
        print*, B(2)%A%A_double(:)  ! nothing printed
        print*, 'Hello World_3' 
        !B(2)%A%A_double(1) = 2.d0   ! gives error
    end subroutine try

end module module_try

Jim Dempsey

0 Kudos
marinoni__andrea_mas
2,294 Views

Thank you very much, I didn't get any compilation error/warnings but I changed the code following your suggestion and now the value are printed correctly on the screen as expected. Still, I cannot see the value of the allocated and assigned variables in the watchlist during debugging.

module module_try 
    implicit none
    
    type A_type
        character(len=5) :: A_char      
        double precision, dimension(:), allocatable :: A_double
    endtype A_type
    
    type B_type
        character(len=5) :: B_char
        type(A_type)     :: A
    end type B_type
    
    type(B_type), dimension(:), allocatable :: B
    
contains
    
    subroutine try
        allocate(B(2))               ! no errors
        !allocate(B%A%A_double(3))   ! wrong allocation
        allocate(B(1)%A%A_double(3)) ! no errors, correct allocation
        allocate(B(2)%A%A_double(3)) ! no errors, correct allocation
        B(1)%A%A_double(:) = 1.d0    ! no errros
        B(2)%A%A_double(:) = 2.d0    ! no errors
        print*, 'Hello World_1'
        print*, B(1)%A%A_double(:)
        print*, 'Hello World_2'
        print*, B(2)%A%A_double(:)
        print*, 'Hello World_3' 
        !B(2)%A%A_double(1) = 2.d0
    end subroutine try

end module module_try

I report the modified code and attach what I see from the debugger watch at the end of the routine. As depicted in the picture the debugger cannot show the allocated variables. Do I miss any instruction ?

Thanks in advance, Andrea.

0 Kudos
andrew_4619
Honored Contributor II
2,294 Views

That last point is a debugger bug, What VS/Fortran versions are you using. I think that is fixed now.

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,294 Views

Keep in mind that: "The lack of a compile time error is an error" for the commented out statement, and should be filed as a bug report with Intel.

Andrew's point of compiler version is pertinent when you post forum messages. I do recall having such errors on older versions (with debug finding members of nested user defined types).

Jim Dempsey 

0 Kudos
marinoni__andrea_mas
2,294 Views

Hi all,
Thank you for your suggestions. I will report the lack of compile time error. I am using VS Enterprise 2019 16.2.5 and Intel(R) Visual Fortran Compiler 19.0.5.281 [IA-32], these should also be the latest releases.
Andrea.

0 Kudos
andrew_4619
Honored Contributor II
2,294 Views

Yes, i made a test,  there still seems to be a bug relating the debugger for allocatables in derived types. The code can runs ok it is just the debugger not identifying the target status correctly.

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,295 Views

Here is a complete reproducer for you to submit.

module module_try 
    implicit none
    
    type A_type
        character(len=15) :: A_char      
        double precision, dimension(:), allocatable :: A_double
    endtype A_type
    
    type B_type
        character(len=15) :: B_char
        type(A_type)     :: A
    end type B_type
    
    type(B_type), dimension(:), allocatable :: B
    
contains
    subroutine peek_A(A)
        type(A_type) :: A
        ! when needing to debug, break on following line
        if(.not. allocated(A%A_double) )print *,"Bug"
    end subroutine peek_A
    subroutine try
        allocate(B(2))               ! no errors
        B(1)%B_char = 'B(1)'
        B(2)%B_char = 'B(2)'
        !allocate(B%A%A_double(3))   ! wrong allocation
        print *,allocated(B(1)%A%A_double)
        allocate(B(1)%A%A_double(3)) ! no errors, correct allocation
        B(1)%A%A_char = 'B(1)%A'        ! *** B(1)%A%A_char Visible in Debugger
        B(1)%A%A_double(1) = 123.456    ! *** B(1)%A%A_double .NOT. Visible in Debugger
! ********** VS integration error *********
! unable to view B(1)%A%A_double in debugger
! Microsoft Visual Studio Professional 2013
! Version 12.0.40629.00 Update 5
! Intel® Parallel Studio XE 2019 Update 3 Composer Edition for Fortran Windows*   Package ID: w_comp_lib_2019.3.203
        call peek_A(B(1)%A)             ! For debugging you can insert something like this
        print *,allocated(B(1)%A%A_double)
        print *,size(B(1)%A%A_double)
        allocate(B(2)%A%A_double(3)) ! no errors, correct allocation
        B(1)%A%A_double(:) = 1.d0    ! no errros
        B(2)%A%A_double(:) = 2.d0    ! no errors
        print*, 'Hello World_1'
        print*, B(1)%A%A_double(:)
        print*, 'Hello World_2'
        print*, B(2)%A%A_double(:)
        print*, 'Hello World_3' 
        !B(2)%A%A_double(1) = 2.d0
    end subroutine try

end module module_try

program Nested
    use module_try
    call try
end program Nested

Note to Intel, the nested allocatable array is not visible in both Win32 and x64 Debug builds.

Jim Dempsey

0 Kudos
Giannakos__Vassileio
1,774 Views

Greetings,

does anyone know if this issue is resolved? And if so, in which update?

0 Kudos
FortranFan
Honored Contributor II
2,294 Views

Another in situ option to the workaround the Intel Fortran deficiency in its integration with Visual Studio integration is to use the ASSOCIATE construct:

bug.PNG

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,294 Views

FortranFan, excellent suggestion (you earn the best response). This avoids writing peek functions.

The only additional suggestion would be to include the "never true" IF test that the compiler cannot determine is never true. This would permit you to have working code with little overhead when not debugging as well as not having the compiler optimize out the desired code. Andrea, be aware that inserting this/these statement(s) will disable vectorization for this section of code.

Also,

If you use the FPP (preprocessor), you could #define an FPP macro to conditionally insert the inspection helper.

! *** compile with FPP enabled

subroutine PEEK_HACK
end subroutine PEEK_HACK
! then at break, use Call Stack window to focus on caller

#define PEEK(a) \
   associate(PEEK_AT => a) ; CALL PEEK_HACK ; end associate

module module_try 
    implicit none
    
    type A_type
        character(len=15) :: A_char      
        double precision, dimension(:), allocatable :: A_double
    endtype A_type
    
    type B_type
        character(len=15) :: B_char
        type(A_type)     :: A
    end type B_type
    
    type(B_type), dimension(:), allocatable :: B
    
contains
    subroutine try
        allocate(B(2))               ! no errors
        B(1)%B_char = 'B(1)'
        B(2)%B_char = 'B(2)'
        !allocate(B%A%A_double(3))   ! wrong allocation
        print *,allocated(B(1)%A%A_double)
        allocate(B(1)%A%A_double(3)) ! no errors, correct allocation
        B(1)%A%A_char = 'B(1)%A'        ! *** B(1)%A%A_char Visible in Debugger
        B(1)%A%A_double(1) = 123.456    ! *** B(1)%A%A_double .NOT. Visible in Debugger
! ********** VS integration error *********
! unable to view B(1)%A%A_double in debugger
! Microsoft Visual Studio Professional 2013
! Version 12.0.40629.00 Update 5
! Intel® Parallel Studio XE 2019 Update 3 Composer Edition for Fortran Windows*   Package ID: w_comp_lib_2019.3.203
        PEEK(B(1)%A)             ! For debugging you can insert something like this, use step into
        print *,allocated(B(1)%A%A_double)
        print *,size(B(1)%A%A_double)
        allocate(B(2)%A%A_double(3)) ! no errors, correct allocation
        B(1)%A%A_double(:) = 1.d0    ! no errros
        B(2)%A%A_double(:) = 2.d0    ! no errors
        print*, 'Hello World_1'
        print*, B(1)%A%A_double(:)
        print*, 'Hello World_2'
        print*, B(2)%A%A_double(:)
        print*, 'Hello World_3' 
        !B(2)%A%A_double(1) = 2.d0
    end subroutine try

end module module_try

program Nested
    use module_try
    call try
end program Nested

Feel free to derive something from the above. Note, you may have multiple such places to perform this workaround.

To use:

1) When interested in debugging, place Break Point on the PEEK of interest
2) Use Step Into
3) In Call Stack window, set focus on caller

Jim Dempsey

Jim Dempsey

0 Kudos
NsK
Novice
2,193 Views

Sorry to bump that thread but, is there any update on that front???

It's 2020 and this bug is still present (new and shiny VS Fortran compiler 19.1.0057.16 , Visual Studio 16.7.1), becoming a major block now.

Do I have to revert back to my 2017 compiler for the next 30 years ???

 

 

 

0 Kudos
FortranFan
Honored Contributor II
2,180 Views

@NsK ,

If you are able to, please submit a support request providing your details and stating your case forcefully at the Intel Online Support Center: https://supporttickets.intel.com/?lang=en-US.  More customer requests the better.

0 Kudos
Reply