3

Say we have this variable definition

Real*8, Dimension(:), Allocatable :: dblA
Allocate  (dblA(1000))

Now I call this subroutine:

Call MySub(dblA)

In which:

Subroutine MySub(dblA)
Real*8,  INTENT(Out), DIMENSION(1000) :: dblA
End

What is the side effect of such practice? Should I avoid this?

francescalus
  • 30,576
  • 16
  • 61
  • 96
Saeid
  • 691
  • 7
  • 26
  • Please note that `real*8` is not valid Fortran and was never part of any ISO FORTRAN/Fortran standard. Please used named constants from the intrinsic module `ISO_Fortran_env`, or `selected_real_kind` to control precision in a portable manner. – jlokimlin Jan 21 '17 at 01:29

2 Answers2

6

If the array has been allocated prior to being passed to the subroutine the subroutine is indifferent to the allocatable-ness, the effect is the same as if the array were static. There is nothing to object to, nor practice to avoid, in the snippets you show us. However, those snippets actually do very little and it is easy to think of ways to extend them to invalidate this advice.

Now do yourself a favour and change

Real*8,  INTENT(Out), DIMENSION(1000) :: dblA

to

Real*8,  INTENT(Out), DIMENSION(:) :: dblA

so that the subroutine works correctly whatever the size of the array it gets passed. It's probably also a bad idea to use dblA as the name for both the dummy and actual arguments, you'll just confuse yourself.

And real*8 is not, and never has been, a standard-compliant way of declaring an 8-byte real. On this point, see numerous questions and answers here on SO.

High Performance Mark
  • 77,191
  • 7
  • 105
  • 161
5

High Performance Mark's answer says about all I wanted. I will repeat one aspect though, for emphasis.

It is very much required that the allocatable array in the subroutine be allocated when the subroutine is called. [And in the case of the question, of sufficient size.]

To make this answer more than just a comment I'll address the more general question title. Before that, I'll look at things which could feature in the thinking around "allocatable or non-allocatable dummy argument".

  • Because the dummy argument (the one in the subroutine) has the intent(out) attribute it, and the actual argument, becomes undefined. If the dummy argument is allocatable it is also deallocated on entry. In this case, the actual argument remains allocated and of its original size.

  • Without being allocatable, the dummy argument (and the actual argument) cannot have allocation status queried or changed; the dummy argument cannot further be passed to a procedure expecting an allocatable argument even though the actual argument could be.

  • If the dummy argument were allocatable instead of being a (static) explicit shape array, the actual argument must also be an allocatable array.

  • With an allocatable dummy argument an explicit interface would be required when the subroutine is referenced. [Some would say this is a good idea even in the cases where an implicit interface is fine.]

Coming to the more general thing, I'll give an example where there is a restriction on allocatable actual/non-allocatable dummy (F2008, 12.5.2.4):

If the actual argument is a polymorphic coindexed object, the dummy argument shall not be polymorphic.

But this isn't something to worry about for most people.

Oh, and another thing I'll restress from that other answer: Real*8 should be avoided.

Community
  • 1
  • 1
francescalus
  • 30,576
  • 16
  • 61
  • 96
  • Yeah, that's al the stuff I was thinking about but was too idle to write ... :-( – High Performance Mark Jan 16 '17 at 12:09
  • @Francescalus so are you saying the INTENT should be INOUT ? – Holmz Jan 16 '17 at 20:39
  • Not at all, @Holmz. The intent should be whatever is suitable for the use of the dummy argument (or other design considerations). There's a much greater difference between `intent(out)` and `intent(inout)` for an allocatable dummy argument (the former implies deallocation on entry) than there is for an explicit shape array. If you tell me which bit of the answer leads to your question I'll see about clarifying. That could even help the original asker. – francescalus Jan 16 '17 at 20:49
  • @francescalus it seems on ifort that the dimensions of the array are unknown inside of the aubroutine without INTENT(INOUT), hence the question. The desire I had was to use OUT, but i found that the INOUT is needed more often than not. – Holmz Jan 17 '17 at 06:58
  • @Holmz, when there's an explicit shape array dummy argument (such as in the original question) or an assumed shape array, use of `intent(inout)` shouldn't be necessary to have the bounds of the dummy (resp., effective) argument available. For an allocatable (pointer) _dummy_ argument the effective argument is deallocated (resp., becomes of undefined association status) on entry to the subroutine - losing the shape detail. Without seeing your code (perhaps question-worthy, but probably off-topic here) I can't say more. – francescalus Jan 17 '17 at 12:33
  • We are refering to the OP's example which shows allocatable in the main. And I was referencing your bullet #1. I'll admit that I usually use some debug to ensure that functions and subroutines are working... and most of the problems seem to happen at the interfaces whether it is code, or wires and connectors. – Holmz Jan 19 '17 at 20:03