2

I have some general questions regarding the arguments passed to a subroutine/function in Fortran, in particolar when it comes to naming of non-local variables.

Given this main program

program xfunc
   implicit none
   real, dimension(5) :: var1, var2
   integer, var3
  ...
  call my_subroutine(var1(i),var2,var3)

SUBROUTINE my_subroutine(arg1,var2,arg3)
    !inout variable not matching the var1 declared in main
    real, intent(inout) :: arg1
    !matches the name and dimension of variable in main, is this needed?
    real, intent(inout), dimension(5) :: var2
    !should arg3 be named var3 since it overwrites the values in var3? And should arg3 have a corresponding variable in the main program
    integer, intent(out) :: arg3
    
end my_subroutine
  1. In the declaration the names are simply "labels", correct? They don't need to match the names of the variables in the main program.
  2. The type dimension of the arguments also don't need to match the ones in the main program, correct? So arg1 (an array) inside the subroutine can be just a real also in the case of an inout variable? They just need to match the declaration INSIDE the subroutine? Does this apply only for intent(in) arguments?
  3. Do the variables need to be declared inside the subroutine even if they are "inout" and match exactly the ones in the main program?
  4. What's good practice when naming the arguments and variables of subroutines or functions? Should different names be used to distinguish them from the main program? I am curious about this question especially for all variables that are (inout and out).
Herman Toothrot
  • 1,463
  • 3
  • 23
  • 53
  • What you have given is not a valid "declaration" of a subroutine, and as a result it's not entirely clear to me what you mean in the rest of the equation. It would really help if you provide at least both sides (calling and callee) so you can show clearly the differences you are asking about, and better still would be a complete program illustrating the points you want to make. – Ian Bush Jun 08 '20 at 13:11
  • @IanBush I understand, I was trying to ask mostly generic questions but tried to add some short code to make some examples. – Herman Toothrot Jun 08 '20 at 13:44

2 Answers2

3

This is a question about argument association. Intent of arguments is largely irrelevant to this discussion.

In the procedure (subroutine or function) declaration, the "labels" are the names of entities which have the procedure as their scope. In the declaration of my_subroutine of the question these entities have names arg1, var2 and arg3. These are the dummy arguments of the procedure. The names of these dummy arguments are entirely unrelated to the names of entities in other scopes (more or less, anything that isn't that procedure). Argument intent does not affect the naming or association.

Entities in other scopes, such as the main program of the question, are different things. However, when there is a procedure reference, such as the subroutine call, there is established an association between the arguments in the referencing place (the actual arguments) and the entities local to the procedure (again, the dummy arguments). Name is not a factor in this association: the actual arguments and the dummy arguments do not need to have the same name. Indeed (and regardless of intent), the actual arguments don't even need to be names.

Within each scope (main program, procedure) the corresponding names are used.

As part of the argument association, we don't simply say "argument 1 in the main program is the same thing as argument 1 in the procedure". There are many aspects to this, but we can say here that this means (in response to sub-question 2): dummy and actual arguments in general don't need to have the same shape (either number of elements, or rank). In many cases there are restrictions on shape. Intent is not a factor here. Inside the procedure the dummy argument has the characteristics of its declaration, independent (except for any matching restrictions which may be in place) of the characteristics of the actual argument.

Further, it's possible to have an array element actual argument correspond to an array dummy argument (but not a scalar actual argument). This uses storage association about which you can see many other questions here.

On the contrary, it isn't possible to have an array actual argument correspond to a scalar dummy argument for non-elemental procedures.

If an entity is not a dummy argument of a procedure then there must be some other form of association to get the entity of the main program accessible inside the scope of the procedure. This could be host association, use association, storage association (or linkage association). In any event, without declaration as a dummy argument the entity is not a dummy argument. Again, intent plays no part here.

I won't touch on sub-question 4 (being rather subjective) except to say that helping users debug problematic code is much easier when entities in different scopes have different names: "the dummy variable x of function foo, which is argument associated with actual argument x in the main program, which is in term use associated with module variable x of bar" gets a bit tedious to keep straight.

francescalus
  • 30,576
  • 16
  • 61
  • 96
  • Thank you for the answer, it definitely helps better understand how code should be structured. – Herman Toothrot Jun 10 '20 at 12:01
  • There's one thing I still don't understand. You mentioned the intent doesn't make a difference, but then how does the subroutine know that the quantity of arg3 in the example needs to be written in var3 once the procedure is finished? – Herman Toothrot Jun 10 '20 at 12:17
  • 1
    That `var3` is "updated" by changes to `arg3` is the point of the argument association. But changes aren't written to `var3` once the procedure is finished: the two variables are essentially the same thing when the procedure is being executed. (Compilers may handle this as copy-in/copy-out with a temporary, but that's a different topic. In this case you may perhaps think of "pass-by-reference" rather than "pass-by-value". Subtleties lie in both aspects.) – francescalus Jun 10 '20 at 13:52
  • So the argument association is done even without the use of intent, correct? – Herman Toothrot Jun 10 '20 at 15:44
  • 1
    Yes. Argument association the process by which the procedure affects and is affected by the outside world through its dummy arguments. Argument intent (mostly) describes what _type_ of effects are possible. – francescalus Jun 10 '20 at 15:52
2

1) Yes : the names of actual arguments don't have to match the names of dummy arguments.

2) Yes and no : the size of declared arguments must be, at least, less than or equal to the size of actual arguments (not strictly exact…). Notice that it exists several manners to declare dimensions of dummy arguments; The advised one is, which requires an explicit interface, is (:) in your case which allows the subroutine to get the exact size or argument with the intrinsic SIZE function.

3) Yes, they need : the intent clause does not matter. intent(inout) only adds a check of the compiler.

4) No general rule. My rule : If a subroutine is called only once (or a few call statements) in a code, then usually names should match. This is just easier to understand.

Francois Jacq
  • 1,244
  • 10
  • 18
  • Regarding 2) I think the OP means different Rank, when talking about dimension. – mcocdawc Jun 08 '20 at 20:24
  • Thanks for the answer, helps me understand more. I meant either Rank or Size. – Herman Toothrot Jun 10 '20 at 12:00
  • Usually, the subroutine or function imposes the rank of arrays (number of indexes for each array). But the recent Fortran norm (2018) authorizes to declare arrays with arbitrary rank. Unfortunately, I never tried this possibility. I just remember a déclaration with (..) – Francois Jacq Jun 10 '20 at 13:07