5

I have created an allocatable array. I allocate the elements and then I print the size of the array. I find strange that the size remains the same after a deallocate.

  Integer, Allocatable :: fred(:)
  Allocate (fred(3))
  Write (*,*) "fred: ", Size (fred)
  Deallocate (fred)
  Write (*,*) "fred: ", Size (fred)
Zeus
  • 1,485
  • 1
  • 17
  • 33
  • 2
    That isn't valid Fortran code: any result you get is allowed for a Fortran processor. – francescalus Jul 13 '15 at 00:05
  • What are you talking about? – Zeus Jul 13 '15 at 00:13
  • I've answered, but I am actually interested in what you believe the correct output to be. – francescalus Jul 13 '15 at 00:43
  • 3
    @Zeus what he means is that if your code does not conform to the standard, then it is not valid Fortran. If the code is outside of the standard, then there is nothing that defines what "correct" behavior means, and this means that any behavior is correct. See the C language concept of "undefined behavior". Fortran doesn't use that term, but the concepts apply. – casey Jul 13 '15 at 02:39
  • You could have been a bit more specific. You mean that you cannot call `Size` on an array which has not been allocated? – Zeus Jul 13 '15 at 12:42
  • 1
    @Zeus download a copy of the standard and familiarize yourself with it. Specifically, look at Fortran 2008 Cl. 13.7.156 paragraph 3. `It shall not be an unallocated allocatable variable` referring to the argument of `SIZE`. – casey Jul 13 '15 at 18:12

1 Answers1

11

This is a question crying out for a canonical one, really. In the interest of answering your specific question in the absence (as far as I can tell, but I may write one eventually), I'll answer.

The argument to size must not be an unallocated allocatable variable.

For your code fred is an allocatable variable. If this block of code is executed then on the final line size has an argument which is an unallocated allocatable variable. In this case if it forms part of a program (program unit) then that program (program unit) is not a standard conforming program (program unit).

This lack of conformance is not a lack of conformance that a Fortran processor is required to detect to be a conforming Fortran processor.

Yes, it would be nice for the processor to detect this, and many will if you choose the appropriate options at compile time. A standard conforming processor will be allowed, in the popular parlance, to start World War III in response to this code. It may also print 3. That is entirely down to the whim of the compiler vendor.

Prompted by the comments, more information.

It's tempting, perhaps, to expect that the size of a deallocated array is zero. However, a deallocated array and an array with zero elements are quite different things, much as a character of length zero is not the same as an unallocated allocatable character.

In particular, we have idioms like

fred = [fred, append]

which are not valid when fred is not allocated, but are when it is allocated but of size zero; and it doesn't need special treatment in this latter case.

I agree with High Performance Mark's comment that, if the compiler is going to return any value, 0 is a bad choice. Much as the size isn't well defined any attempt to access fred(3), say, based on the returned size, is also a bad idea. Again, the compiler is free to give any particular value for this reference.

Finally, if you want to check whether an array is allocated you should use the allocated intrinsic rather than rely on size returning 0. Of course, in this case it isn't needed as you can be quite sure that after the deallocate statement fred is indeed not allocated.

In Fortran 90 it was possible for allocation status to be undefined and then even allocated wasn't allowed.


The same ideas apply for things other than arrays and the size intrinsic. size is an inquiry function which requires the array inquired about to be allocated (if an allocatable entity) or pointer associated (if a pointer). Equally, for example, a character with deferred length must be allocated/pointer associated (as applicable) to be an argument to the len intrinsic inquiry function.

Inquiry functions don't always require arguments to be allocated/associated. For example, the length of a character of explicit length may be asked about even if the variable is not allocated. One should check the requirements in documentation and not make inquiries which are not allowed.

francescalus
  • 30,576
  • 16
  • 61
  • 96
  • You could always check with `Allocated (fred`) – Zeus Jul 13 '15 at 12:44
  • I do use allocated to check, however, when the program calls the delete routine, I want to show him that there is no data available, so I show a value 0. He can then populate it with the data he wants. – Zeus Jul 14 '15 at 11:59
  • There was possibly an implicit question that I didn't notice (I tend to not notice any context from the question - which is my fault). If you can explain more clearly what it is you are wanting I'll try again to answer. Fundamentally, though, a non-allocated array should (by compiler and programmer) be treated quite differently from a size-0 allocated array. – francescalus Jul 14 '15 at 12:45
  • It's ok. Knowing that the compiler has the size with an undefined status for unallocated variables answered my question. – Zeus Jul 15 '15 at 13:50