View previous topic :: View next topic |
Author |
Message |
simon
Joined: 05 Jul 2006 Posts: 299
|
Posted: Tue Aug 24, 2010 5:36 pm Post subject: Array bound checking |
|
|
The following code allocates an array with one dimension size 0, but does not give an array bounds error message when compiled with /CHECK. It's not obvious to me whether ALLOCATE should have returned non-zero, but it does not.
Code: |
PROGRAM p1
INTEGER :: n=0,m=5
INTEGER :: i,ifail
INTEGER, ALLOCATABLE :: a(:,:)
INTRINSIC SHAPE,SIZE
!
ALLOCATE (a(n,m),STAT=ifail)
IF (ifail/=0) STOP
PRINT *, SIZE(a)
PRINT*, SHAPE(a)
DO i=1,m
a(:,i)=i
END DO
PRINT *, a
END PROGRAM p1 |
|
|
Back to top |
|
 |
Sebastian
Joined: 20 Feb 2008 Posts: 177
|
|
Back to top |
|
 |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8210 Location: Salford, UK
|
Posted: Tue Aug 24, 2010 9:34 pm Post subject: |
|
|
This is a very interesting program.
The Fortran standard does not appear to say anything about whether ALLOCATE should fail for a zero size array so the compiler writer has a choice.
Try compiling the program with /explist and look at the resulting .lis file.
a(:,i) = i is expanded as a do loop that is not entered. Hence it does not fail with the /check mechanism.
As in the suggested link, the problem will become apparent when you try to access elements of the array. |
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2615 Location: Sydney
|
Posted: Wed Aug 25, 2010 4:44 am Post subject: |
|
|
Paul,
My understanding is that the Standard does specifically address the size of zero. ( I don't have a copy of the Standard!!) I recall many years ago Tom Lahey explaining this aspect of arrays in Fortran 90/95.
The array can be defined, and used as in an argument list of subroutines.
You can use it in array expressions, but can not use it when referencing elements of the array, as they do not exist.
I have code, where I "think" I have now implemented this usage. I'll need to check.
John |
|
Back to top |
|
 |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8210 Location: Salford, UK
|
Posted: Wed Aug 25, 2010 8:32 am Post subject: |
|
|
Thanks John. This being the case, FTN95 is correct in this respect. |
|
Back to top |
|
 |
simon
Joined: 05 Jul 2006 Posts: 299
|
Posted: Wed Aug 25, 2010 2:17 pm Post subject: |
|
|
Thanks to all. I am wondering whether the line
could potentially overwrite some other memory. I guess this may be compiler specific, but does anything actually happen in this do loop? |
|
Back to top |
|
 |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8210 Location: Salford, UK
|
Posted: Wed Aug 25, 2010 7:38 pm Post subject: |
|
|
Nothing happens because the do loop is not entered.
The test comes first and is false.
There are no items in the array to assign a value to. |
|
Back to top |
|
 |
Sebastian
Joined: 20 Feb 2008 Posts: 177
|
Posted: Thu Aug 26, 2010 10:11 am Post subject: |
|
|
Quote: | Nothing happens because the do loop is not entered. |
What do-loop is not entered? The one in the posted code snippet surely is (upper loop boundary is 5).
Quote: | Thanks to all. I am wondering whether the line
a(:,i) = i
could potentially overwrite some other memory. |
I don't remember if is affected as well or if twodimensional arrays are special with regard to the check issue, but (used by times in initialization routines) DOES corrupt memory for a zero-allocated array, see the linked posting. |
|
Back to top |
|
 |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8210 Location: Salford, UK
|
Posted: Thu Aug 26, 2010 2:07 pm Post subject: |
|
|
As I have already indicated in this thread the do loop is not the explicit do loop in the code but the one supplied by the compiler in order to expand
a(:,i) = i.
Quote: | a(:,i) = i is expanded as a do loop that is not entered |
|
|
Back to top |
|
 |
Sebastian
Joined: 20 Feb 2008 Posts: 177
|
Posted: Thu Aug 26, 2010 3:17 pm Post subject: |
|
|
Quote: | As I have already indicated in this thread the do loop is not the explicit do loop in the code |
This was not apparent to me from the context, thanks for clarification.
Quote: | Nothing happens because the do loop is not entered.
The test comes first and is false.
There are no items in the array to assign a value to. |
So the : qualified argument has no problem, but the unqualified (a=0). The latter occurring a lot in legacy code here, hard to track. |
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2615 Location: Sydney
|
Posted: Fri Aug 27, 2010 1:53 am Post subject: |
|
|
Sebastian,
Where does "a = 0" fail?
Your link had the problem of addressing an array which was not allocated, not an allocated array of size zero.
I'd be interested to find out if a zero size allocated array produced the problem, as I have coded this and not found the problem, as yet.
Your code below, as modified does not show any apparent problems for me.
John Code: | program alloc
integer, allocatable, dimension(:) :: array
!
allocate (array(0))
array = 0
write (*,*) size(array)
write (*,*) 'Array :',array
print*, "Should not reach this."
end program alloc |
|
|
Back to top |
|
 |
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Sun Aug 29, 2010 7:38 am Post subject: |
|
|
I don't think there is any problem. Zero size arrays have been added as a new feature since Fortran 90. The ALLOCATE statement produces an array of zero size.
The loop
Code: |
DO i=1,m
a(:,i) = i
END DO
|
may be compiled as
The loop
Code: |
DO k=1,n
DO i=1,m
a(k,i) = i
END DO
END DO
|
may be compiled as
The following statements do not generate any code.
I think the FTN95 compiler does all these things correctly. |
|
Back to top |
|
 |
Sebastian
Joined: 20 Feb 2008 Posts: 177
|
Posted: Sun Aug 29, 2010 2:41 pm Post subject: |
|
|
Quote: | Where does "a = 0" fail?
Your link had the problem of addressing an array which was not allocated, not an allocated array of size zero. |
You are right, the crash only happens if the array is unallocated and the file is compiled using non-check/non-checkmate parameters. The bug is that check/checkmate does not trigger an error.
But it's unrelated to the zero-sized arrays which is the topic of the thread. |
|
Back to top |
|
 |
|