I spent quite a bit of time debugging an application that in the end boils down to the code below:
PROGRAM MAIN IMPLICIT NONE INTEGER,ALLOCATABLE :: ARRAY(:),I ALLOCATE(ARRAY(5)) ARRAY = [1,2,3,4,5] WRITE(*,*) (ARRAY(I),I=1,5) END PROGRAM MAIN
This triggers an access violation. Obviously the declaration of the variable I is incorrect (it should not be declared as allocatable), but I am surprised that the compiler lets this slide. Maybe my understanding of this is not complete. In what circumstances "INTEGER,ALLOCATABLE :: I" (without a DIMENSION statement somewhere else in the code) would be acceptable and what would it mean?
This is with 16 Update 2.
integer, allocatable :: fred allocate(fred) fred=5
the above code seems perfectly acceptable. Fred is undefined prior to the allocate. How useful that code is is a different question....
With Fortran 2003 compatibility (/standard-semantics), you don't even need the allocate statement prior to the assignment.
(Use of a variable in an implied do loop is not equivalent to assignment.)
Allocatable scalars are often used for polymorphic objects, objects that have deferred type parameters, where there is a need for finer control over the lifetime of the object or where there is a need to indicate missing or optional data.
ok - thank you for the comments.
I am aware of scalar polymorphic objects and other 'complex' cases where ALLOCATABLE can be used (and is, in fact, necessary) - I just didn't know this syntax was also available for the 'simple' scalar data types INTEGER, REAL, etc. I agree with andrew_4619 the usefulness of such statement is debatable.
Anyway - this silly coding error is now corrected :-)
It's not a coding error - the code is valid F2003. However, up through the current (16.0) version, the Intel compiler default is to not do the automatic (re)allocation on assignment to an allocatable array. I expect this to change in the next major release later this year. /standard-semantics turns on this feature as well as others where our defaults don't match the standard.
Note that you don't get this for scalars, but DO get it for deferred-length allocatable character variables (even in 16.0).
I wrote the following code just last night...
!> Not allocated if we have not yet seen the FIXED keyword. If we !! have seen the FIXED keyword, this is allocated and has the value !! of the integer literal constant. INTEGER, ALLOCATABLE :: fixed
This is as a derived type component. There are easy alternative approaches (carrying around a separate "is_present" flag to the value), but from the point of view of the definition status of an object of the derived type, the allocatable scalar component is neater conceptually and practically - if it is not allocated, the value simply doesn't exist and doesn't affect the definition status of its containing object.
Special casing the simple types would arguably result in a more complex language, and I suspect more complicated processor implementation. If you couldn't have scalars of intrinsic type, people would be asking "why not?".
I see. Things are more clear on my side now, thanks for the example IanH. I usually address the existence/definition of such scalars by assigning them a default value (say, HUGE(1)), but I see that your approach is applicable to broader scenarios (with LOGICAL variables, or any scalar of any type for that matter).
Steve, I am not sure I understand your statement "Note that you don't get this for scalars" - are you referring to automatic (re)-allocation on right-hand side assignment for a scalar? I did a small test (see modified code below), and depending on whether I turn on or off /standard-semantics (F2003) I get an access violation or not. This is (I think) expected, and therefore this is why I am confused by your statement regarding scalars.
PROGRAM MAIN IMPLICIT NONE INTEGER,ALLOCATABLE :: ARRAY(:),I I = 1 ALLOCATE(ARRAY(5)) ARRAY = [1,2,3,4,5] WRITE(*,*) (ARRAY(I),I=1,5) END PROGRAM MAIN