rtrwalker
rtrwalker

Reputation: 1021

Use variable from fortran subroutine argument list to set module variable of the same name

I have a whole bunch of variables defined in a Fortran module called. I want to have a subroutine that, at its simplest, initializes the module level variables to those provided by the user. The simplified code below works, however, I've had to use a dummy variable "iii_" in the subroutine argument list to ultimately set the value of module variable "iii". Is there any way to use the same variable name in the subroutine argument list and the module?

  MODULE foo        
    IMPLICIT NONE
    INTEGER :: iii

    CONTAINS
      SUBROUTINE initilize(iii_)
        IMPLICIT NONE
        INTEGER :: iii_
        iii = iii_
        print *, iii
      END SUBROUTINE
  END MODULE

So what I really want is:

  MODULE foo        
    IMPLICIT NONE
    INTEGER :: iii

    CONTAINS
      SUBROUTINE initilize(iii)
        IMPLICIT NONE
        [code to set subroutine iii to module iii]
        print *, iii
      END SUBROUTINE
  END MODULE

Upvotes: 1

Views: 808

Answers (2)

chw21
chw21

Reputation: 8140

I don't know why you would need this. So far I can only see two options:

  1. iii is private, in which case it would be easier to give it a different name alltogether (you can't access it from outside anyway)

  2. iii needs to be available to the using routine, in which case you can set it directly rather than using a separate setter method.

So I think you, or anyone looking at this solution, should first think hard about whether and why they need this.

That said, here's an idea that seems to work. The problem is that the locally declared variable iii hides the original iii because it has the same name. I'm using a pointer to give me a second access to that module-wide variable:

module foo_mod
    implicit none
    integer, target :: iii
    integer, pointer, private :: p_iii => iii

    contains

        subroutine initialize(iii)
            implicit none
            integer, intent(in) :: iii
            p_iii = iii
        end subroutine initialize

end module foo_mod

program bar

    use foo_mod
    implicit none

    call initialize(4)
    print *, iii

end program bar

Upvotes: 1

Alexander Vogt
Alexander Vogt

Reputation: 18098

No. You cannot have a module variable and a dummy argument with the same name in the same scope, the later would take precedence and you would have no access to the module variable in the subroutine.

You could, however, have a second module just for initialization and use the module variables from foo with another name:

MODULE bar
  CONTAINS
    SUBROUTINE initilize(iii)
      USE foo, ONLY: iii_ => iii
      IMPLICIT NONE
      INTEGER :: iii

      iii_ = iii
    END SUBROUTINE
END MODULE

Upvotes: 2

Related Questions