Herman Toothrot
Herman Toothrot

Reputation: 1533

Fortran subroutine/function arguments names and declaration

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).

Upvotes: 2

Views: 1844

Answers (2)

francescalus
francescalus

Reputation: 32451

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.

Upvotes: 3

Francois Jacq
Francois Jacq

Reputation: 1274

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.

Upvotes: 2

Related Questions