Private function in Fortran - fortran

How do I declare a private function in Fortran?

This will only work with a Fortran 90 module. In your module declaration, you can specify the access limits for a list of variables and routines using the "public" and "private" keywords. I usually find it helpful to use the private keyword by itself initially, which specifies that everything within the module is private unless explicitly marked public.
In the code sample below, subroutine_1() and function_1() are accessible from outside the module via the requisite "use" statement, but any other variable/subroutine/function will be private.
module so_example
implicit none
private
public :: subroutine_1
public :: function_1
contains
! Implementation of subroutines and functions goes here
end module so_example

If you use modules, here is the syntax:
PUBLIC :: subname-1, funname-2, ...
PRIVATE :: subname-1, funname-2, ...
All entities listed in PRIVATE will not be accessible from outside of the module and all entities listed in PUBLIC can be accessed from outside of the module. All the others entities, by default, can be accessed from outside of the module.
MODULE Field
IMPLICIT NONE
Integer :: Dimen
PUBLIC :: Gravity
PRIVATE :: Electric, Magnetic
CONTAINS
INTEGER FUNCTION Gravity()
..........
END FUNCTION Gravity
REAL FUNCTION Electric()
..........
END FUNCTION
REAL FUNCTION Magnetic()
..........
END FUNCTION
..........
END MODULE Field

I've never written a line of FORTRAN, but this thread about "Private module procedures" seems to be topical, at least I hope so. Seems to contain answers, at least.
jaredor summary:
The public/private attribute exists within modules in Fortran 90 and later. Fortran 77 and earlier--you're out of luck.

Private xxx, yyy, zzz
real function xxx (v)
...
end function xxx
integer function yyy()
...
end function yyy
subroutine zzz ( a,b,c )
...
end subroutine zzz
...
other stuff that calls them
...

Related

Can we Modify the accessibility of Type-bound Procedures in Fortran

MODULE MyTypeMod
TYPE MyType
PRIVATE
INTEGER, ALLOCATABLE :: Num
CONTAINS
PROCEDURE, PUBLIC :: IsNum!To check Allocation of Num
...
END TYPE MyType
CONTAINS
...
END MODULE MyTypeMod
PROGRAM testMyType
USE MyTypeMod, ONLY : MyType
...
END PROGRAM testMyType
Here In this Module and Program, Can we modify accessibility status "IsNum" type-bound procedure? Can we make the "IsNum" procedure PRIVATE in just the testMyTypeMod PROGRAM?
According to paragraph 9 of section 7.5.5 of the Fortran 2018 draft standard
A public type-bound procedure is accessible via any accessible object of the type. A private type-bound procedure is accessible only within the module containing the type definition, and within its descendants.
And so changing the accessibility of a type-bound procedure is not possible.
There is currently a proposal to update a future Fortran standard that suggests making a subset of what you want to do possible.
You may want to make a new proposal to update the standard. This is also likely the best way to find out why what you want to do is not currently possible.

From module, use only some components of a derived data type

Consider this simple module:
module mod1
implicit none
type namespace
integer :: int1
real :: real1
endtype
type(namespace) :: namespace1
end module mod1
Now I want to import just int1 from this derived datastructure namspace1, so as to keep track of what variable came from where.
Following program give an error:
program tmp
use mod1, only: int1 => namespace1%int1
implicit none
print *, int1
end program tmp
I get the following error
Error: Syntax error in USE statement at (1)
Is there some way to only use requires components from a derived datatype? or I need to do use mod1, only: nm => namespace1 followed by nm%int1 only?
Components cannot be selectively USE'd into other scopes.
Components within a type can be made PRIVATE to the defining module and its descendants, but this prevents them from being accessed in all other program units.
Fortran derived types are not suitable as a namespace management prop.

How to pass a private variant value into declaration when overide new functions

For instance, I have a definition of type A in moduleA:
Module moduleA
implicit none
type A
private
integer::N
contains
...
procedure,pass::f=>f1
endtype
private::f1
contains
real function f1(self,x)
real::x(self%n)
end function
...
end Module
Then I found I meet a trouble when I override function f in other modules since I can not get the value of N. Even though I can have a method to get that, it seems that something like real :: x(self%get()) is impossible in the declaration. I want to keep the rule of "private" in OPP. So what choices can I have?
You cannot do that. At least in the way you describe. It would be better to see an example of the overriding to suggest other options.
The private attribute works differently in Fortran and therefore you should not directly use rules from other languages that use OOP where private means something different.
In Fortran private is about the local module, in C++ it is about the derived classes. This is very different and you cannot use the C++ (or Java, etc.) rules for private in Fortran when private in fact means something else.
To be clear, I assume you wanted this kind of overriding:
real function f2(self,x)
class(B) :: self
real::x(self%get())
end function
You than get these messages:
private.f90(15): error #8497: Illegal use of a procedure name in an expression, possibly a function call missing parenthesis. [GET]
real::x(self%get())
---------------------^
or
real::x(self%get())
1
Error: 'get' at (1) should be a FUNCTION
So the compilers will not accept a type-bound procedure in the declaration. They would accept an ordinary procedure.
This compiles in gfortran, but not in Intel Fortran. But get() must be public, which you might not want:
real function f1(self,x)
class(A) :: self
real::x(get(self))
end function
real function f2(self,x)
class(B) :: self
real::x(get(self))
end function
In ifort I get
error #8383: The dummy arguments of an overriding and overridden binding that correspond by position must have the same characteristics, except for the type of the passed object dummy arguments.
which is weird.

fortran module use wrong

The following is the code skeleton from VASP. My work is that porting it on one new platform. And when I use the compiler of that platform, I got the error. If I comment out the use m and I also get "It must have an explicit interface specified." I just want to make a minimum modification to avoid incurring errors into other parts of the program.
module m
interface
subroutine a
end subroutine
end interface
interface
subroutine b
end subroutine
end interface
end module
subroutine a
use m
call b
end subroutine
In the code as shown, the interface for subroutine a defined in the module is accessible inside subroutine a via use association. Because a subprogram already defines an explicit interface for any procedures that it defines, this means that you have two separately defined explicit interfaces for the same procedure accessible in the same scope. This is a violation of the rules of the language (F2008 12.4.3.2p7).
You can use the ONLY clause on the USE statement to exclude the interface body variant of the subroutines interface from being made accessible by use association inside the subroutine.
module m
interface
subroutine a
end subroutine
end interface
interface
subroutine b
end subroutine
end interface
end module
subroutine a
use m, only: b
call b
end subroutine
Why not simply:
module m
contains
subroutine b
! code
end subroutine b
subroutine a
! code
call subroutine b
end subroutine a
end module m
From what you've posted I don't see any recursion (neither subroutine calls itself, a calls b but b doesn't call a) nor any need for it. Nor do I see a need for explicitly writing interface blocks; package the subroutines into a module and let the compiler take care of checking interface specifications and agreement.

Making an enum public

Is it possible to make an enum public, in a module where the default is private?
module mod
private
enum, (public,) bind(c) !Doesn't work
enumerator(, public) :: ENUM1, ENUM2,... !Doesn't work
end enum
end module
I want to keep the module data private by default but want the enums to be public without having to list them individually like this:
public :: ENUM1, ENUM2,... !Works
I understand that enums are just integer parameters so I'm curious if it's possible to do it for all of them at once.
What you are trying to do does not conform the syntax rules from Fortran 2008 4.6.1., therefore, it is not possible to insert the public attributes in the enumeration definition.
There is also no way to put the enumerators in the public statement as a group, you must list each of them.
The enumerations were added to Fortran more or less only for C interoperability (note the obligatory bind(c)) and do not fit the rest of the language that well.