# Why I can access private module variable in this program?

**URL:** <https://fortran-lang.discourse.group/t/why-i-can-access-private-module-variable-in-this-program/5092>\
**Category:** Help\
**Created:** [January 27, 2023, 1:29am UTC](https://fortran-lang.discourse.group/t/why-i-can-access-private-module-variable-in-this-program/5092 "2023-01-27T01:29:12Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![imronuke](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/imronuke/32/2499_2.png) [@imronuke](https://fortran-lang.discourse.group/u/imronuke)\
**Post date:** [January 27, 2023, 1:29am UTC](https://fortran-lang.discourse.group/t/why-i-can-access-private-module-variable-in-this-program/5092/1 "2023-01-27T01:29:12Z")

</div>

Hello all,

This is my first post here.

I just need a help to explain why I can access (both read and write) private module variable `x` in this program? is it a bug or I understood the private clause incorrectly?

```auto
imronuke@imronuke-p02:$ cat test.f90 
module foo1

    private

    real :: x = 1
    
end module

module foo2

    use foo1

    real :: y = 2

end module

program test

    use foo2

    x = 5
    write(*,*) x, y

end program

```

after compiling and running

```auto

imronuke@imronuke-p02:$ gfortran test.f90 -o test
imronuke@imronuke-p02:$ ./test
   5.00000000 2.00000000    

```

I am using gfortran 11.3.0

```auto
imronuke@imronuke-p02:~$ gfortran --version
GNU Fortran (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

```

Thanks all.

---

<div class="post-metadata">

**Author:** ![dwwork](https://avatars.discourse-cdn.com/v4/letter/d/71e660/32.png) [@dwwork](https://fortran-lang.discourse.group/u/dwwork)\
**Post date:** [January 27, 2023, 1:38am UTC](https://fortran-lang.discourse.group/t/why-i-can-access-private-module-variable-in-this-program/5092/2 "2023-01-27T01:38:26Z")

</div>

You need to add ‘implicit none’ in each module and in your main program. Without you, are implicitly declaring a variable called ‘x’ in your main program, which is difference from the one in the module.

---

<div class="post-metadata">

**Author:** ![imronuke](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/imronuke/32/2499_2.png) [@imronuke](https://fortran-lang.discourse.group/u/imronuke)\
**Post date:** [January 27, 2023, 1:48am UTC](https://fortran-lang.discourse.group/t/why-i-can-access-private-module-variable-in-this-program/5092/3 "2023-01-27T01:48:55Z")

</div>

> You need to add ‘implicit none’ in each module and in your main program. Without you, are implicitly declaring a variable called ‘x’ in your main program, which is difference from the one in the module.

OMG, how come I forgot this basic thing. Thank you.

---

<div class="post-metadata">

**Author:** ![jacobwilliams](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/jacobwilliams/32/10_2.png) [@jacobwilliams](https://fortran-lang.discourse.group/u/jacobwilliams)\
**Post date:** [January 27, 2023, 2:01am UTC](https://fortran-lang.discourse.group/t/why-i-can-access-private-module-variable-in-this-program/5092/4 "2023-01-27T02:01:59Z")

</div>

Implicit typing strikes again.

---

<div class="post-metadata">

**Author:** ![imronuke](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/imronuke/32/2499_2.png) [@imronuke](https://fortran-lang.discourse.group/u/imronuke)\
**Post date:** [January 27, 2023, 2:18am UTC](https://fortran-lang.discourse.group/t/why-i-can-access-private-module-variable-in-this-program/5092/5 "2023-01-27T02:18:11Z")

</div>

Continuing the discussion from [Why I can access private module variable in this program?](https://fortran-lang.discourse.group/t/why-i-can-access-private-module-variable-in-this-program/5092/4):

> Implicit typing strikes again.

Yes, yes. IMHO, this is should have been enabled by default in modern Fortran compilers unless stated otherwise. I know there has been a long debate on this in the Fotran Community.

---

<div class="post-metadata">

**Author:** ![FortranFan](https://avatars.discourse-cdn.com/v4/letter/f/96bed5/32.png) [@FortranFan](https://fortran-lang.discourse.group/u/FortranFan)\
**Post date:** [January 27, 2023, 4:04am UTC](https://fortran-lang.discourse.group/t/why-i-can-access-private-module-variable-in-this-program/5092/6 "2023-01-27T04:04:30Z")

</div>

> [@imronuke](#):
>
> IMHO, this is should have been enabled by default in modern Fortran compilers

@imronuke ,

Welcome to the discourse!

Fortran compilers, barring LFortran, do not appear at all keen to enable explicit typing by default. For them, there are always these **unnamed** but “bigger” and “more important” customers who won’t like that. That’s a real, real shame, both on these “customers” - who I reckon are entirely on taxpayer dole and thus can resist low-level changes like doing away with the implicit mapping in Fortran until hell freezes over - and on the compilers. But that’s how it will be.

So look into `-fimplicit-none` option if you are using `gfortran`.

---

<div class="post-metadata">

**Author:** ![Harper](https://avatars.discourse-cdn.com/v4/letter/h/b5ac83/32.png) [@Harper](https://fortran-lang.discourse.group/u/Harper)\
**Post date:** [January 27, 2023, 8:31pm UTC](https://fortran-lang.discourse.group/t/why-i-can-access-private-module-variable-in-this-program/5092/7 "2023-01-27T20:31:24Z")

</div>

One “bigger” and “more important” customer was the US Department of Defense. They introduced  
`implicit none` in MIL-STD-1753 in 1978 as an extension to f77. That forced vendors to implement it (and various other features that seem much less contentious) if they wanted DoD to buy their compilers.

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [January 27, 2023, 9:20pm UTC](https://fortran-lang.discourse.group/t/why-i-can-access-private-module-variable-in-this-program/5092/8 "2023-01-27T21:20:38Z")

</div>

> [@FortranFan](#):
>
> So look into `-fimplicit-none` option if you are using `gfortran`.

This is to give a balanced perspective of this approach. If you use the compiler option to “fix” the code, then you must use that option every time you compile your code from now to infinity. And everyone else who uses that code must do the same thing, from now to infinity. But if you put the declaration in the source once, just one single time, then it is fixed forever, and neither you nor anyone who uses the code will ever need to worry about it again, from now to infinity.

---

<div class="post-metadata">

**Author:** ![FortranFan](https://avatars.discourse-cdn.com/v4/letter/f/96bed5/32.png) [@FortranFan](https://fortran-lang.discourse.group/u/FortranFan)\
**Post date:** [January 27, 2023, 9:57pm UTC](https://fortran-lang.discourse.group/t/why-i-can-access-private-module-variable-in-this-program/5092/9 "2023-01-27T21:57:48Z")

</div>

> [@RonShepard](#):
>
> This is to give a balanced perspective of this approach …

Readers can appreciate OP understands the need to include `implicit none` in each relevant scope but inadvertently missed out on doing so. OP shows 3 such scopes in the original post itself, but may have many more in actual code. Under the circumstances, the best guard rail is to also use the `-fimplicit-none` compiler option. OP can then proceed to use the compiler error messages to guide with the introduction of `implicit none` in the scopes as well as explicitly declare the types of the objects in question.

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [January 27, 2023, 10:32pm UTC](https://fortran-lang.discourse.group/t/why-i-can-access-private-module-variable-in-this-program/5092/10 "2023-01-27T22:32:23Z")

</div>

> [@FortranFan](#):
>
> OP can then proceed to use the compiler error messages to guide with the introduction of `implicit none` in the scopes as well as explicitly declare the types of the objects in question.

I agree with this. If compiler options help the programmer fix the code, then I think that is good. If they are used to compile nonconforming code indefinitely, as is often the case, then that is not good. In this case, it looks like the former situation.

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [January 27, 2023, 10:50pm UTC](https://fortran-lang.discourse.group/t/why-i-can-access-private-module-variable-in-this-program/5092/11 "2023-01-27T22:50:41Z")

</div>

> [@imronuke](#):
>
> ```auto
> program test
> 
> use foo2
> 
> x = 5
> write(*,*) x, y
> 
> end program
> 
> ```

Wouldn’t it be useful if a programmer could, at any point in the program, print out the names and the sources of all variables that are in scope? If that were done here, then the programmer could have easily seen that `y` is imported from the module `foo2` and that `x` is a local variable, which is probably not what was expected.

As a matter of style, some programmers always use the `only:` clause with `use` statements. If that had been done here, the program might have looked something like

```auto
program test
    use foo2, only: x, y
    x = 5
    write(*,*) x, y
end program

```

and the compiler would know at compile time that `x` cannot be imported from the module `foo2` (presumably as intended). Of course, `implicit none` would be a good idea too. In this case, both conventions could be used together.

---

<div class="post-metadata">

**Author:** ![imronuke](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/imronuke/32/2499_2.png) [@imronuke](https://fortran-lang.discourse.group/u/imronuke)\
**Post date:** [January 29, 2023, 12:54am UTC](https://fortran-lang.discourse.group/t/why-i-can-access-private-module-variable-in-this-program/5092/13 "2023-01-29T00:54:26Z")

</div>

> [@RonShepard](#):
>
> As a matter of style, some programmers always use the `only:` clause with `use` statements. If that had been done here, the program might have looked something like

Thank you for your comment. I used to be like that in writing Fortran programs. Later, I personally found that is not practical on a large project. For example I need to write `use foo, only: x,y,z,bla,bla,..` which often there are teens of module variables/methods in that statement which I think is verbose. And if I modified my program, I need to take care that statement again by adding or removing module variables/methods. I prefer to use private or public clauses to control which variables/methods that can be used outside the module. Well, again, it is just matter of style.

---

<div class="post-metadata">

**Author:** ![imronuke](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/imronuke/32/2499_2.png) [@imronuke](https://fortran-lang.discourse.group/u/imronuke)\
**Post date:** [January 29, 2023, 1:05am UTC](https://fortran-lang.discourse.group/t/why-i-can-access-private-module-variable-in-this-program/5092/14 "2023-01-29T01:05:26Z")

</div>

> [@FortranFan](#):
>
> For them, there are always these **unnamed** but “bigger” and “more important” customers who won’t like that.

Thank you for the comment. I came up with an idea that perhaps solve everyone problems, including those big customers: the `implicit none` shall be enabled by default on all Fortran files except the ones with extensions `*.f` and `*.f77`. However, if necessary, this behavior can be altered using a compiler flag.

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [January 29, 2023, 1:25am UTC](https://fortran-lang.discourse.group/t/why-i-can-access-private-module-variable-in-this-program/5092/15 "2023-01-29T01:25:01Z")

</div>

> [@imronuke](#):
>
> I prefer to use private or public clauses to control which variables/methods that can be used outside the module. Well, again, it is just matter of style.

Yes, public/private declarations are useful too. But the `only:` clause serves a different purpose. If you want to know which module an entity comes from, then if the `only:` clause is used, you just look at the local use statements and there is the answer. Without that, the programmer would need to search the source code for each individual module, and also each module that they use in turn, to locate the source.

Of course, `only:` does other things too. If there are multiple modules with entities with the same name, then `only:` provides a way to pick the one you want. And back to the other point, a programmer looking at the local code can see from which of the multiple possible modules the entity is imported.

The downside for this is that it places more burden on the programmer as he is writing and maintaining the code. Some compilers can warn the programmer at compile time if an entity is mentioned in an `only:` clause but is not used in the code. That helps the programmer keep the lists clean. The other problem is when there are dozens of entities that are included in each `only:` clause, all of which are actually referenced. It is perhaps easy to search these lists with a text editor to locate the important one, but it is more difficult for the programmer to just look at the code and find it. Ironically, it is larger programs, perhaps with shared modules spread over several directories, where the `only:` clause lists become most useful, and it is those cases also that tend to have the larger lists. An upside is that all of this checking is done by the compiler at compile time, so it is relatively fast and easy to do this as a code is being developed or refactored. If the check required runtime tests, perhaps with input data that specifically tested the relevant parts of the code, it would be overall a more difficult burden on the programmer than it is.

---

<div class="post-metadata">

**Author:** ![ivanpribec](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ivanpribec/32/3290_2.png) [@ivanpribec](https://fortran-lang.discourse.group/u/ivanpribec)\
**Post date:** [January 29, 2023, 9:57am UTC](https://fortran-lang.discourse.group/t/why-i-can-access-private-module-variable-in-this-program/5092/16 "2023-01-29T09:57:01Z")

</div>

The ability to specify which entities are imported is one of the things I really like about Fortran in comparison to C/C++, where it can take a lot of detective work to figure out the origin of some entity. In some cases your code may work because of a transitive include, but when you refactor it and remove a header which is not needed anymore, your code breaks because of a missing include.

C++ modules were introduced to resolve such problems; my own experience so far has been that learning the the distinct rules for modules/namespaces/headers is a burden. For example [here](https://vector-of-bool.github.io/2019/03/10/modules-1.html) is a three-part series on C++ modules which is hard to cover in one sitting.

---

<div class="post-metadata">

**Author:** ![imronuke](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/imronuke/32/2499_2.png) [@imronuke](https://fortran-lang.discourse.group/u/imronuke)\
**Post date:** [January 30, 2023, 12:55am UTC](https://fortran-lang.discourse.group/t/why-i-can-access-private-module-variable-in-this-program/5092/17 "2023-01-30T00:55:58Z")

</div>

> [@RonShepard](#):
>
> Yes, public/private declarations are useful too. But the `only:` clause serves a different purpose. If you want to know which module an entity comes from, then if the `only:` clause is used, you just look at the local use statements and there is the answer. Without that, the programmer would need to search the source code for each individual module, and also each module that they use in turn, to locate the source.

I can do this in VS Code equipped with Modern Fortran extension with a single button. Even, I can find the implementations of an entity in the other part of the project by a combination of buttons. This makes my life much easier (thanks to the developers Hansen and @gnikit)

> [@RonShepard](#):
>
> Of course, `only:` does other things too. If there are multiple modules with entities with the same name, then `only:` provides a way to pick the one you want. And back to the other point, a programmer looking at the local code can see from which of the multiple possible modules the entity is imported.

Yes completely agree. I use `only` in case there is naming conflict or when the entities that are used are few. Thanks Ron for the discussion 🙂

---

<div class="post-metadata">

**Author:** ![FLNewbiee](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/flnewbiee/32/2155_2.png) [@FLNewbiee](https://fortran-lang.discourse.group/u/FLNewbiee)\
**Post date:** [January 31, 2023, 9:40am UTC](https://fortran-lang.discourse.group/t/why-i-can-access-private-module-variable-in-this-program/5092/18 "2023-01-31T09:40:30Z")

</div>

Unintentionally, it has been left that passing variables from modules is something acceptable/tolerant which could be a misleading idea to new users.

IMHO, passing variables from modules should be avoided. Modules are used to containerized code. Except of functions/subroutines, types, (and other structural declarations/definitions) a module may also contain `PUBLIC` `PARAMETER`s which are **fixed** variables (eg. PI) to avoid re-declaration of them within the scope of a code block (eg library).

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [January 31, 2023, 4:08pm UTC](https://fortran-lang.discourse.group/t/why-i-can-access-private-module-variable-in-this-program/5092/19 "2023-01-31T16:08:40Z")

</div>

> [@imronuke](#):
>
> IMHO, this is should have been enabled by default in modern Fortran compilers unless stated otherwise.

Indeed, and it is in LFortran:

```auto
$ lfortran a.f90
semantic error: Variable 'x' is not declared
  --> a.f90:21:5
   |
21 | x = 5
   | ^ 'x' is undeclared
$ lfortran --implicit-typing a.f90
5.00000000e+00 2.00000000e+00

```

Other compilers could do the same I think.

Your original code currently compiles with LFortran but not because of implicit typing, but because we have a bug with private variables ([Disallow importing private variables · Issue #1239 · lfortran/lfortran · GitHub](https://github.com/lfortran/lfortran/issues/1239)), which we’ll fix soon.

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [January 31, 2023, 4:32pm UTC](https://fortran-lang.discourse.group/t/why-i-can-access-private-module-variable-in-this-program/5092/20 "2023-01-31T16:32:19Z")

</div>

> [@FLNewbiee](#):
>
> IMHO, passing variables from modules should be avoided.

The problem with such blanket declarations is that there are so many exceptions, they are often misleading. There are only so many ways that a subroutine can access some datum. It can be local, or a dummy argument, imported from a parent subprogram, through a pointer, a common block, or a module. Many times, of all the possibilities, importing from a shared module is the best approach.

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [January 31, 2023, 5:19pm UTC](https://fortran-lang.discourse.group/t/why-i-can-access-private-module-variable-in-this-program/5092/22 "2023-01-31T17:19:02Z")

</div>

> [@certik](#):
>
> Your original code currently compiles with LFortran but not because of implicit typing, […]

Didn’t you just show above this statement in your comment that it was indeed the `--implicit-typing` option that allowed it to compile and execute?

I also wanted to point out another feature of `implicit none`, which also applies to the equivalent compiler options. With either the standand default implicit mapping or with any other explicitly declared mapping, the implicit rules in place can affect how the code is compiled. If the implicit mapping in effect as the time applies to any undeclared entity, then it obviously affects the properties of that entity, specifically, its type and kind. If the implicit mapping is changed, it changes that entity.

But `implicit none` is different in this respect. With implicit none in effect throughout the code, there are no undeclared entities. The type and kind properties of each entity are determined with some kind of explicit declaration. This means that any program that compiles with `implicit none` in effect would compile exactly the same way with some other implicit declaration, including the fortran standard default implicit mapping. So when it comes to compiling code, implicit none does absolutely nothing in the end. Its real purpose is during the program writing stage, to help the programmer recognize any missing declarations. In this respect, `implicit none` is an odd language feature.

Going back to the original code in this discussion, the mistake was that the programmer thought (incorrectly) that `x` was imported from a module, when in fact it was a local variable that was implicitly typed (real with the default kind). As discussed above, there are two things that could be done so that the compiler could catch this error. One is to invoke implicit none (preferably in the source code, but also with a compiler option). The programmer could then decide exactly what he wanted that `x` to be, imported from the module or a local variable. If he chose to declare it locally, then at that point there would no implicitly declared variables remaining, and the `implicit none` could be removed and the code would thereafter compile correctly. If instead the programmer realized that he wanted to import that variable, then one option would have been to add `x` and `y` to the `only:` clause. Simply doing that, with no change to the implicit mapping, would have resulted in a compile time error (barring the above mentioned compiler error). Namely the compiler would have recognized that `x` could not be imported due to its private attribute within its module.

[Next page](https://fortran-lang.discourse.group/t/why-i-can-access-private-module-variable-in-this-program/5092.md?page=2)
