Using a function inside another function inside a module [duplicate] - module

This question already has answers here:
Why is this a function declared inside the module and then used somewhere else in the same module not seen by the linker?
(2 answers)
Fortran function in a module not found by subroutine in the same module [duplicate]
(1 answer)
Closed 3 years ago.
I have functions and subroutines in my module. Then I use that module inside the main program. But inside my module there is function where I call another function. While I compile that it says undefined reference in Fortran.
module A
implicit none
real*8 :: k(1:4),ls(1:4)
contains
function B(p,q)
implicit none
real*8 :: p,q,B
B=p+q
end function B
subroutine C(u,v,res)
implicit none
real*8 :: u,v,res,B
res=B(u,v)
end subroutine
end module A
program main
use A
implicit none
real*8 :: Out
call C(4.d0,3.d0,out)
write(*,*) out
end program main
I would like to get 7.0d0 ,but I am getting undefined reference in Fortran for B.

Related

Fortran: class in abstract interface [duplicate]

This question already has answers here:
Why is the type not accessible?
(2 answers)
Closed 6 years ago.
Using cygwin64 on Windows this program won't compile:
program test
implicit none
!define my type
type myType
real::foo
integer::bar
end type myType
!define an operator for this type
interface operator (>)
logical function compare(a,b)
type(myType),intent(in) :: a,b
compare = a%foo>b%foo
end function compare
end interface operator (>)
!simple example of operator usage
type(myType) :: tfoo, tbar
tfoo = card(1.,2); tbar = card(3.,4)
print*, tfoo>tbar
end program test
gfortran (only argument is "std=f2008") tells me:
type(myType),intent(in) :: a,b
1
Error: Derived type ‘mytype’ at (1) is being used before it is defined
which is confusing to me, since the type is defined right before the operator. I'm relatively new to Fortran, so this example code might have some more errors.
The same problem occurred here, but encapsulating myType in a separate module did not resolve the issue.
There are several issues with your code, but this particular error is because myType is in the host scope, but not in the interface block. The solution is to either place the derived type in a separate module as suggested in the linked thread, or import the derived type from the host scoping unit:
interface operator (>)
logical function compare(a,b)
import myType
type(myType),intent(in) :: a,b
end function compare
end interface operator (>)
This is described in the Fortran 2008 Standard, Cl. 12.4.3.3 "IMPORT statement":
1 The IMPORT statement specifies that the named entities from the host scoping unit are accessible in the interface
body by host association. An entity that is imported in this manner and is defined in the host scoping unit shall be
explicitly declared prior to the interface body.
An interface block may not have executable statements included - so the assignment you have there is not valid. Furthermore, card is not defined in your code.

Undefined reference when calling an external function of the same module [duplicate]

This question already has answers here:
Why is this a function declared inside the module and then used somewhere else in the same module not seen by the linker?
(2 answers)
Undefined reference to procedure defined in the same module [duplicate]
(1 answer)
Fortran function in a module not found by subroutine in the same module [duplicate]
(1 answer)
Closed 2 years ago.
I have a number of functions in a module, and I need one function to use other of the same module as the input of of a third function.
FUNCTION FUN2(W)
use gabqs, only: GABQ2
IMPLICIT REAL*8 (A-H,O-Z)
! REAL*8 W
EXTERNAL FUN3
R1 = 1.e-5
R2 = 10.e0
TOL = 1.E-2
CALL GABQ2(FUN3,R1,R2,SUM2,TOL,IER)
Fun2=sum2*W
RETURN
END
FUNCTION FUN3(R)
use dielectricFun, only: elflev
IMPLICIT REAL*8 (A-H,O-Z)
REAL*8 K,W
PI=3.1415926536
CALL elflev(w,k,r,ximelf)
fun3=ximelf*4.d0*pi*(r**2.d0)
RETURN
END
I can compile the module but when I compile the main program i get an error in the module where the two functions are:
.\integralfun.o:integralFun.F90:(.text+0x16c): undefined reference to `fun3_'
I have all the use statement in the main program.

How to handle Fortran global allocatable variables in a module across subroutines

I have the following module with an allocatable variable which is defined in the module, allocated in a subroutine, and then also used in a second subroutine called by the first subroutine. In this situation do I have to pass the variable to the second subroutine and declare INTENT(inout)? Or since it's a global variable it doesn't need to be passed as an argument?
MODULE test
IMPLICIT NONE
SAVE
REAL,ALLOCATABLE,DIMENSION(:,:,:) :: total
CONTAINS
!--- 1st subroutine
SUBROUTINE my_subr1(n,m,z)
IMPLICIT NONE
INTEGER,INTENT(in) :: n,m,z
ALLOCATE(total (n,m,z))
total=.9
CALL my_subr2(n)
END SUBROUTINE my_subr1
!-- 2nd subroutine
SUBROUTINE my_subr2(n)
IMPLICIT NONE
INTEGER,INTENT(in) :: n
total(n,:,:)=total(n-1,:,:)
END SUBROUTINE my_subr2
END MODULE test
do I have to pass the variable to the second subroutine and declare INTENT(inout)?
No, you don't. Any variable decalred in the body of the module has the save attribute by default. You must, though, ensure that the second subroutine is only called after the first was executed, or else the program will fail because total would not be initialized yet.
All functions and subroutines declared in the module will have access to total by host association.
By the way, there are some issues you should address in your code, as mentioned by #PierredeBuyl in the comments:
Variables declared in the module body are saved by default; you should remove the SAVE statement.
Procedures declared in a module inherit the IMPLICIT directive from the module scope, there is no need to redeclare it in the subroutine if you won't change it.
You are missing the declaration of the arguments in my_subr1.

Fortran function in a module not found by subroutine in the same module [duplicate]

This question already has answers here:
Why is this a function declared inside the module and then used somewhere else in the same module not seen by the linker?
(2 answers)
Closed 4 years ago.
I am writing a module in Fortran90, Mainly I defined a function inside the module, and a subroutine that uses the function. Here's an excerpt of the module
module Mesh_io
implicit none
private
contains
integer function findkey ( )
content of this function
end function
subroutine getNumber_Mesh ()
integer :: findkey
content of the routine
end subroutine getNumber_Mesh
end module
When compiling I get the following output:
objects/Main.o: In function `__mesh_io_MOD_getnumber_mesh':
Main.f90:(.text+0x9e): undefined reference to `findkey_'
As you can see the function is contained in the module, but for some reason the compiler can not find it.
With the declaration of findkey inside the subroutine getNumber_Mesh() you are creating a local variable findkey that hides the function.
With modules, it is not required to declare the return value of functions (of module functions). Simply removing the declaration should do the trick.

Is "intent" guaranteed for contained subroutines inside a module contained subroutine?

I am wondering if the following code is legal:
module my_mod
contains
subroutine my_outer_sub(a)
integer, intent(in) :: a
call my_inner_sub()
contains
subroutine my_inner_sub()
a=3 ! this compiles and runs!
end subroutine my_inner_sub
end subroutine my_outer_sub
end module my_mod
I compiled the code with PGI 17.4. I have been using contained subroutines inside module subroutines and now I wonder if this scheme is a suitable one?
No, the code is illegal. You cannot modify an intent(in) argument. This is an error in the compiler and should be reported to your vendor.
Gfortran identifies it correctly
Error: Dummy argument 'a' with INTENT(IN) in variable definition context (assignment) at (1)
and so does Intel Fortran
intent3.f90(11): error #6780: A dummy argument with the INTENT(IN) attribute shall not be defined nor become undefined. [A]
a=3 ! this compiles and runs!
------^
compilation aborted for intent3.f90 (code 1)