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

"Undefined Pointer/Array" when allocating subelements of (nested) arrays of derived type

Francesco_F
Novice
1,284 Views

I'm writing a Fortran code (IFORT Intel Fortran Compiler Classic on Visual Studio Community) and I was considering the possibility of defining a nested structure of derived type elements like in the example.
In summary, I have elements like "myGround%LevelA1(nn)%m(d)" where m(:) is ALLOCATABLE, and in principle I don't need LevelA to be ALLOCATABLE.

What I get is that myGround%LevelA1(nn)%m(d) is labeled as "Undefined Pointer/Array"  by the debugger even after allocation. In the end, the code works, also in debug mode, but I assume there is something that confused the debugger.

My question is: what is the best way to define this structure?

My temporary solution is: if the child element m(:) is allocatable, also the mother LevelA(:) should be allocatable.

 

In the following example I have a derived type tHome, that contains (I apologyze for my use of vocabulary, I hope the reader may understand what I mean. If I write fortran-blasphemies, you are welcome to correct me) other three variables LevelA1, LevelA2 and LevelA3 (of a corresponding derived type tLevelA1, tLevelA2 and tLevelA3). In particular, LevelA1 and LevelA2 are already allocated at the definition ("ALLOCATED"), while LevelA2 is ALLOCATABLE.

All these derived types tLevelA# contain a sub-element, which is an ALLOCATABLE (m(:), n(:) for tLevel1 and tLevel2, respectively) and "ALLOCATED" for tLevel3.

For the variable Level3 (type tLevel3) everything is already allocated, and there is no problem.

For the variable Level2 (type tLevel2) everything is allocatable, and there is not problem.

For the variable Level1 (type tLevel1) the mother (Level1) is "ALLOCATED", while the child m(:) is ALLOCATABLE. After allocation of myGround%LevelA1(nn)%m(d), the debugger shows myGround%LevelA1(nn)%m to be an "Undefined pointer/array", even if the PRINT shows the correct expected results.

This question is partially related to https://community.intel.com/t5/Intel-Fortran-Compiler/Allocatable-Array-of-Inherited-Derived-Types-Issues-in-Fortran/td-p/1012026 

 

many thanks in advance

 

 

 

MODULE MyMod
    IMPLICIT NONE
    PUBLIC
    INTEGER, PARAMETER :: d = 4 
    
    TYPE, public :: tLevelA1
        REAL, ALLOCATABLE :: m(:)   
    END TYPE tLevelA1
        
    type, public :: tLevelA2
        REAL, ALLOCATABLE :: n(:)   
    end type tLevelA2
         
    type, public :: tLevelA3
        REAL :: o(d)   
    end type tLevelA3
         
    
    TYPE, PUBLIC :: tGround
        TYPE(tLevelA1) :: LevelA1(d)                ! => Debugger is confused (sub-elements are allocatable)
        TYPE(tLevelA2), ALLOCATABLE :: LevelA2(:)   ! => OK (sub-elements are allocatable)
        TYPE(tLevelA3) :: LevelA3(d)                ! => OK (sub-elements are not allocatable)
    END TYPE tGround
     
    TYPE, PUBLIC ::  tHome 
        TYPE(tGround) :: Ground
    END TYPE tHome
     
    CONTAINS
     
    function ConstructorHome() Result(myHome)
        IMPLICIT NONE 
        type(tHome) :: myHome
        
        myHome%Ground = ConstructorGround()
        ! 
    end FUNCTION ConstructorHome
     
    function ConstructorGround() Result(myGround)
        IMPLICIT NONE
        type(tGround) :: myGround 
        type(tLevelA2) :: locA2(d) 
        type(tLevelA1) :: locA1(d) 
        INTEGER :: nn
        ALLOCATE(myGround%LevelA2(d))
        DO nn=1,d 
            ALLOCATE(myGround%LevelA1(nn)%m(d)) 
            ALLOCATE(myGround%LevelA2(nn)%n(d)) 
            ALLOCATE(locA1(nn)%m(d))     
            ALLOCATE(locA2(nn)%n(d))   
        ENDDO 
        DO nn=1,d   
            myGround%LevelA1(nn)%m(:)       = 10.0  + nn
            myGround%LevelA2(nn)%n(:)       = 20.0  + nn
            myGround%LevelA3(nn)%o(:)       = 30.0  + nn
        ENDDO 
        DO nn=1,d   
            PRINT *, myGround%LevelA1(nn)%m(:)
            PRINT *, myGround%LevelA2(nn)%n(:)
            PRINT *, myGround%LevelA3(nn)%o(:)
        ENDDO 
        PRINT *,"-------------------" 
        myGround%LevelA1  = locA1
        myGround%LevelA2  = locA2
        DO nn=1,d   
            myGround%LevelA1(nn)%m(:)       = 10.0  + nn
        ENDDO 
        DO nn=1,d   
            PRINT *, myGround%LevelA1(nn)%m(:)
            PRINT *, myGround%LevelA2(nn)%n(:)
            PRINT *, myGround%LevelA3(nn)%o(:)
        ENDDO 
        
        ! 
        DO nn=1,d   
            DEALLOCATE(myGround%LevelA2(nn)%n)      
        ENDDO 
        ! 
    end function ConstructorGround
    
    
         

END MODULE MyMod
    

PROGRAM mytest
    USE MyMod
    IMPLICIT NONE
    TYPE(tHOME) :: myHome
    
    myHome = ConstructorHome()
    
END PROGRAM mytest
    

 

 

Labels (2)
1 Solution
Devorah_H_Intel
Moderator
808 Views

@Francesco_F  The fix is in recently released compiler, part of HPC Toolkit 2023.2

View solution in original post

0 Kudos
10 Replies
FortranFan
Honored Contributor II
1,252 Views

@Francesco_F ,

Consider the following silly code:

   type :: a_t
      integer, allocatable :: x(:)
   end type
   type :: b_t
      type(a_t) :: a(2)
   end type
   type :: c_t
      type(b_t) :: b
   end type
   type(c_t) :: c
   allocate( c%b%a(1)%x(2), source=1 )
   allocate( c%b%a(2)%x(3), source=2 )
   print *, c%b%a(1)%x(1)
   print *, c%b%a(2)%x(2)
end   

Upon building and execution, it works as expected:

 1
 2
Press any key to continue . . .

However, if one places a breakpoint at the line 13 during a debugger session in Visual Studio and views the object, the "Undefined pointer/array" info will be noticed:

u.PNG

This has nothing to do with the specific Fortran code, rather it is a gap/limitation of the Intel Fortran integration with Visual Studio.

This is an issue which has long been present in form or other, at least for 10 years or more.  Yet Intel Software team has NOT been able to bring sufficient attention and resources to resolve this problem.

It's beyond shameful.

But there is nothing the customers can do other than use "tricks": one such option - not that I always recommend it - is to use ASSOCIATE construct with temporary code used for debugging.  For example,

u.PNG

 

Francesco_F
Novice
1,246 Views

I thank you for the kind and quick reply, you were very helfpful, even if unfortunately the proposed solution can only be a work-around of the problem.

In that case, I would prefer the use of ALLOCATABLE: type(a_t), ALLOCATABLE :: a(:)

   type :: a_t
      integer, allocatable :: x(:)
   end type
   type :: b_t
      type(a_t) :: a(2)
      type(a_t), ALLOCATABLE :: aa(:)   ! => this is fine for VS
   end type
   type :: c_t
      type(b_t) :: b
   end type
   type(c_t) :: c
   allocate( c%b%a(1)%x(2), source=1)
   allocate( c%b%a(2)%x(3), source=2)
   ALLOCATE(c%b%aa(2))
   allocate( c%b%aa(1)%x(2), source=1)
   allocate( c%b%aa(2)%x(3), source=2)
   print *, c%b%a(1)%x(:)
   print *, c%b%a(2)%x(:)
   print *, "--------------------------"
   print *, c%b%aa(1)%x(:)
   print *, c%b%aa(2)%x(:)
end 

In this way we don't need to use the ASSOCIATE construct to do debugging (in general I never use prints, this was just to look at the real bahaviour of the code).

screenshot.png

 

0 Kudos
FortranFan
Honored Contributor II
1,197 Views

You can do whatever works out for you, but know that rejigging one's class definitions (such as with your thought of making a certain component of a type composition derived type with the ALLOCATABLE attribute) in order to function with an outdated and gap-ridden debugger extension in Visual Studio is neither always possible nor advisable, in many circumstances that will be akin to placing the cart before the horse.  Also, there is no guarantee such refactoring will always work with the Intel debugger.  With components of derived type and other objects, with Intel Fortran integration with Visual Studio, "Undefined pointer/array" is a rather common encounter.

But if that's what you prefer, more power to you.

0 Kudos
JohnNichols
Valued Contributor III
1,180 Views

The same thing happens with parameters, you cannot see them.  I realize they are not variables, but it would be nice to see them in watch otherwise you need to look them up. 

0 Kudos
Steve_Lionel
Honored Contributor III
1,167 Views

PARAMETER constants are visible in the debugger if you select the option /debug-parameters:[none/used/all]

0 Kudos
Devorah_H_Intel
Moderator
1,106 Views

@Francesco_F  Over the past years, we have successfully resolved numerous debugger issues.

Currently, we are actively working on fixing a new issue that you have submitted. If you come across any additional debugger issues, we kindly request you to submit them on this forum for our attention and resolution. 

jimdempseyatthecove
Honored Contributor III
1,068 Views

>>If you come across any additional debugger issues, we kindly request you to submit them on this forum for our attention and resolution. 

While I do not have a reproducer handy, on MS VS 2019

block
  real :: somevar
  ...
  somevar = expression
  (break on line following, somevar not visible)
  ...
end block

IOW variables declared within a block are not visible in the debugger when within the block. Those variables outside the block remain visible as expected.

 

Jim Dempsey

Devorah_H_Intel
Moderator
1,030 Views

Thank you, @jimdempseyatthecove - for reporting this to us. We are working on the issue.

0 Kudos
Devorah_H_Intel
Moderator
809 Views

@Francesco_F  The fix is in recently released compiler, part of HPC Toolkit 2023.2

0 Kudos
FortranFan
Honored Contributor II
800 Views

That's great @Devorah_H_Intel .  Please see this comment in another ongoing thread:

https://community.intel.com/t5/Intel-Fortran-Compiler/Intel-oneAPI-segmentation-fault-on-valid-F2018-code/m-p/1505243#M167254

Will it be possible for you to follow-up on that more complicated case where the "undefined pointer/array" issue persists.

Thanks,

0 Kudos
Reply