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

Issue with allocatable scalars?

OP1
New Contributor II
714 Views

The code below may reflect my own lack of understanding... I was expecting that the allocation status of II would be transferred to JJ (just as it is for J) when executing line 7. As it is, the code triggers an access violation when executing that line.

PROGRAM P
IMPLICIT NONE
INTEGER,ALLOCATABLE :: I(:),J(:)
INTEGER,ALLOCATABLE :: II,JJ
J  = I
WRITE(*,*) ALLOCATED(J)
JJ = II
WRITE(*,*) ALLOCATED(JJ)
END PROGRAM P

This is with 19 Update 3, on a Win 10 machine.

0 Kudos
9 Replies
JohnNichols
Valued Contributor III
714 Views

Unless I am sorely mistaken you actually need to allocate the arrays with a size. - 

ALLOCATE(matrix(3,5),vector(-2:N+2))       ! specifies shapes

You are missing the shape component and the error code at the end

0 Kudos
OP1
New Contributor II
714 Views

John - scalars can be declared as allocatable; this is actually useful as a mechanism to detect whether they have been defined or not.

0 Kudos
andrew_4619
Honored Contributor II
714 Views

Well lines 5 and 7 would allocate LHS but given the RHS is unallocated and  thus undefined  to my mind your code is non-conforming and I would not expect it to "work". 

I am not sure what you mean by "this is actually useful as a mechanism to detect whether they have been defined or not.". If they are not allocated then I would say they are not defined but if they are allocated they could still be uninitialised? Could you elaborate as I might be missing a new trick here.

0 Kudos
Steve_Lionel
Honored Contributor III
714 Views

Both assignments are invalid according to the standard, since I and II are not allocated. There is no "transfer of allocation status" here. If you compile with pointer checking enabled, you get:

forrtl: severe (408): fort: (8): Attempt to fetch from allocatable variable I when it is not allocated

Image              PC                Routine            Line        Source
t.exe              00007FF719B35166  Unknown               Unknown  Unknown
t.exe              00007FF719B310A3  MAIN__                      5  t.f90

 

0 Kudos
OP1
New Contributor II
714 Views

Thanks Steve - I really thought that the assignment was valid for the arrays; in the sense that even if the right hand side array is not allocated, it still has a descriptor - and that the content of that descriptor would be copied to the descriptor of the left-hand side array in the J = I assignment.

Regarding andrew_4619 comment... by 'whether they have been defined or not' I meant that testing for the allocation status of the scalar is a way to determine if this scalar has been 'touched' during an initialization procedure. This is useful, for instance, when you deal with a user input which presence is optional.

0 Kudos
jimdempseyatthecove
Honored Contributor III
714 Views

>>This is useful, for instance, when you deal with a user input which presence is optional.

There is a difference with an optional argument not being present and one that is an unallocated alllocatable that was supplied.

Jim Dempsey

0 Kudos
OP1
New Contributor II
714 Views

Jim - this is not what I meant either... Assume that an analysis requires a user parameter and that the user has the choice to explicitly define or omit it altogether. Having an allocatable scalar helps deal with this. Otherwise, each scalar needs to have a companion logical variable like SCALAR_HAS_BEEN_PROVIDED_BY_USER to keep track of this.

0 Kudos
Steve_Lionel
Honored Contributor III
714 Views

nn n. wrote:

Thanks Steve - I really thought that the assignment was valid for the arrays; in the sense that even if the right hand side array is not allocated, it still has a descriptor - and that the content of that descriptor would be copied to the descriptor of the left-hand side array in the J = I assignment.

There is no copying of descriptors. Assignment to an allocatable variable creates new content. It is not like pointer assignment. Yes, there is a descriptor that holds length and bounds info, but it is not really copied verbatim.

0 Kudos
OP1
New Contributor II
714 Views

Steve - I think this is the mistake I made here: I thought that an allocatable array, irrespective of its allocation status, has a descriptor (which contains, among its various bits, information regarding the base address of the array, rank, stride, size of element, allocation status, etc. etc.), and I assumed that an assignment of the type A = B, where both variables are allocatable arrays, would at least initialize the descriptor of A with the allocation status of B.

And beyond that I got it even more wrong thinking that this faulty concept was also applicable to allocatable scalars, ha ha.

0 Kudos
Reply