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

Parameter /check:bounds not applicable for allocated arrays

rase
New Contributor I
751 Views

Is my suspicion correct that the parameter /check:bounds is not applicable for allocated arrays? Is there a possibility to check that the bounds of allocated arrays are not violated, other than an allocation with bounds carefully selected?

0 Kudos
9 Replies
IanH
Honored Contributor II
751 Views

Do you have an example?

PROGRAM check_bounds
  IMPLICIT NONE
  INTEGER, ALLOCATABLE :: array(:)
  
  ALLOCATE(array(5))
  array(6) = 2
END PROGRAM check_bounds

 

>ifort /check:bounds /Od "2016-08-02 check-bounds.f90" && "2016-08-02 check-bounds.exe"
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 16.0.3.207 Build 20160415
Copyright (C) 1985-2016 Intel Corporation.  All rights reserved.

Microsoft (R) Incremental Linker Version 14.00.24210.0
Copyright (C) Microsoft Corporation.  All rights reserved.

"-out:2016-08-02 check-bounds.exe"
-subsystem:console
"2016-08-02 check-bounds.obj"
forrtl: severe (408): fort: (10): Subscript #1 of the array ARRAY has value 6 which is greater than the upper bound of 5

Image              PC                Routine            Line        Source
2016-08-02 check-  00007FF65C9D49BE  Unknown               Unknown  Unknown
2016-08-02 check-  00007FF65C9D125B  Unknown               Unknown  Unknown
2016-08-02 check-  00007FF65C9FD76E  Unknown               Unknown  Unknown
2016-08-02 check-  00007FF65C9FDFE5  Unknown               Unknown  Unknown
KERNEL32.DLL       00007FF8E2B98102  Unknown               Unknown  Unknown
ntdll.dll          00007FF8E4A8C5B4  Unknown               Unknown  Unknown

 

0 Kudos
rase
New Contributor I
751 Views

Sorry, the frantic search for an error which caused a debug interrupt in a complex project caused a temporary blindness for the obvious. Boundary violations are caught allright, also for allocated arrays, if the parameter /check:boundaries is set. IanH, please take my apologies for the extra work to answer my inconsiderate question.

0 Kudos
Andreas_Z_
New Contributor I
751 Views

Related to this topic: Below is an example where the use of an allocatable array and assignments out of allocated bounds do not seem to be detected by /check:bounds.

PROGRAM TestCheckBounds
    
IMPLICIT NONE
INTEGER(4),DIMENSION(6) :: z
!INTEGER(4),DIMENSION(4) :: y !using this declaration (and commenting out line 10) leads the compiler to indicate an error: "The shapes of the array expressions do not conform."
INTEGER(4),DIMENSION(:),ALLOCATABLE :: y

z = [1,2,3,4,5,6]
WRITE(*,*)," z 1: ", z
ALLOCATE(y(4))
y = z   !no error indicated during compilation/run time
WRITE(*,*)," y: ", y
z = y   !no error indicated during compilation/run time
WRITE(*,*)," z 2: ", z
READ(*,*)
!y(5) = z(5)  !this line throws an error (as expected)
    
END PROGRAM TestCheckBounds

In my opinion, the lines y = z and z = y (see comments in code) should cause an error.

The following is the command line used from within Visual Studio 2015 Community, Update 3:
/nologo /debug:full /Od /warn:interfaces /module:"Debug\\" /object:"Debug\\" /Fd"Debug\vc140.pdb" /traceback /check:pointer /check:bounds /check:uninit /check:format /check:output_conversion /check:stack /libs:dll /threads /dbglibs /c

I used the Intel(R) Visual Fortran Compiler 16.0 [IA-32].

 Is it the expected "correct" behavior that an array size (bounds) mismatch is not detected here when an allocatable array 'y' is used  - I find it rather surprising.

Andi

 

 

0 Kudos
Steven_L_Intel1
Employee
751 Views

What you are asking for is shape checking, not really bounds checking. At present we don't do shape checking, so in the contexts where the shapes don't match whether or not you get a bounds error is unpredictable.

If you add the option /standard-semantics (Fortran > Language > Enable Fortran 2003 Semantics) then you'll get Fortran standard automatic reallocation on the allocatable array assignment to y. This (the reallocation on different shape) will be the default in version 17.

0 Kudos
Johannes_Rieke
New Contributor III
751 Views

Some thoughts about shape checking. If you modify line 11 in post #4 of Andi to

y(1:6) = z(1:6)

a shape ckeck is done in run time and an error is thrown. This easy case could be covered in compile time, because the allocation is done with a fixed number, isn't it.

forrtl: severe (408): fort: (2): Subscript #1 of the array Y has value 5 which is greater than the up
per bound of 4

Curiously the other way round (lhs index span smaller than rhs) is found at compile time (modified line 10 and 11):

ALLOCATE(y(6))
y(1:4) = z(1:6)
TestCheckBounds.f90(11): error #6366: The shapes of the array expressions do not conform.   
1>compilation aborted for ... TestCheckBounds.f90 (code 1)

In some more complicated cases (index is a part of a user defined type), I've seen that shape checking works not every time. Unfortunately, I have no minimum working example. (PSXE 2016 up3, win32).

@Steve: Will the new default in 17 (including -assume realloc_lhs) have an impact on the performance in cases where the shapes do not changes, because there is a test in run time?

0 Kudos
Johannes_Rieke
New Contributor III
751 Views

I was able to modify the code above to a case, where shape checking fails:

PROGRAM TestCheckBounds
     
IMPLICIT NONE
INTEGER(4),DIMENSION(6) :: z
!INTEGER(4),DIMENSION(4) :: y !using this declaration (and commenting out line 10) leads the compiler to indicate an error: "The shapes of the array expressions do not conform."
INTEGER(4),DIMENSION(:),ALLOCATABLE :: y
type foo_t
  integer  ::  bar
  integer  ::  barbar
end type foo_t
type(foo_t) :: foo

foo%bar    = 1
foo%barbar = 4

z = [1,2,3,4,5,6]
WRITE(*,*)," z 1: ", z
ALLOCATE(y(6))
y(foo%bar:foo%barbar) = z(1:6)   !no error indicated during compilation/run time
WRITE(*,*)," y: ", y
z = y   !no error indicated during compilation/run time
WRITE(*,*)," z 2: ", z
READ(*,*)
!y(5) = z(5)  !this line throws an error (as expected)     

END PROGRAM TestCheckBounds

No compile time error is thrown, nor a run time error occurs hitting line 19. Is it a defect or are shapes only checked if the bounds are numbers and not variables?

0 Kudos
Steven_L_Intel1
Employee
751 Views

What I said was that the compiler does not check shapes in the current version (except in the case for allocatable array assignment). (We're looking at this for development over the next year, but no promises.) You might get lucky with bounds checking enabled, but many times no error is reported.

Yes, there is overhead for checking the shape on allocatable array assignment when the shapes do conform. We try to keep this as low as possible. You can turn off the feature if you want, but we had many, many customers complain that our default didn't match the standard and, nowadays, most if not all other compilers out there do the reallocation by default.

0 Kudos
Roman1
New Contributor I
751 Views

I have a related question about the new array reallocation feature.  Will it be possible to check that the reallocation was successful?  When I explicitly allocate the array with ALLOCATE, I can check the output STAT variable to make sure that the allocation was successful.

 

0 Kudos
Steven_L_Intel1
Employee
751 Views

The feature isn't new - it's been there for 15 years, but you had to ask for it with /assume:realloc_lhs (or /standard-semantics). The only thing changing is that the default is now  realloc_lhs instead of norealloc_lhs.

The language does not provide a means to query the status of an implicit allocation. You're free to do it yourself (as you had to pre-F2003), and then the change in default makes no difference (other than a bit of overhead for the check.)

There actually is one more change, under the hood. Up through version 16, if you had realloc_lhs enabled the code to do the checking and allocation was all inline, which could sometimes inhibit optimization (since it was a lot of intermediate language). As of version 17 it's done in a library call for much less generated code and potentially better optimization. This also allowed us to clean up the compiler quite a bit, improving reliability.

0 Kudos
Reply