Get warning about unused identifiers from use only - module

Let's say I have the following code:
module test_mod
implicit none
private
public :: A, B, double
integer :: A, C
integer, parameter :: B = 2
contains
integer elemental function double(n)
integer, intent(in) :: n
double = 2 * n
end function
end module
program test_prog
use test_mod, only: A, B, double
implicit none
A = 3
write(*, *) A
end program
If I compile with gfortran -Wall -Wextra I correctly get warnings about:
Unused variable C in test_mod.
Imported but unused variable B in the program.
But I would like to also get a warning about the fact that double is imported, but unused.
Is there a compiler option that I overlook? Is there a compiler that does this?
Is it coming in later versions of gfortran? (I used 8.2.1)

Related

error when calling subroutine from module in fortran [duplicate]

I am trying to compile some really old code (1986 and before). This code references an external function. Today's compilers ask for far more code to make this work. And I keep failing.
I now created a small hello world program, which demonstrates the problem.
hello.for
PROGRAM hello
USE func
PRINT *, "Hello World!"
PRINT *, f ()
END PROGRAM hello
func.for
MODULE func
PUBLIC f
CONTAINS
FUNCTION f ()
f='Hello Func'
END FUNCTION
END MODULE
This has not only one, but two problems:
How do I define the return type? Docs tell <type> FUNCTION <function> or FUNCTION <function> () <type>::<something> , but neither works.
How do I make the linker find the function?
gfortran -c func.for works (if I use the default return type real) and creates a mod file but linking does not work
$ gfortran hello.for
/tmp/ccHNzcXA.o: In function `MAIN__':
hello.for:(.text+0xa4): undefined reference to `__func_MOD_f'
collect2: error: ld returned 1 exit status
__func_MOD_f is not contained in the mod file, but in the o file there is func.for__func_MOD_f.
Any idea?
thanks
You have two issues, the delcaration of f and properly linking the module.
First, compiling the module yields the error:
% gfortran -c func.f
func.f:5:8:
f='Hello Func'
1
Error: Can't convert CHARACTER(1) to REAL(4) at (1)
This error is due to implicit typing of f and an incompatible assignment. Fixing this is simple, declare f explicitly as a character instead of an implicit type. Add:
character(len=30) :: f
to the function and now your module compiles. Here is the modified module:
MODULE func
PUBLIC f
CONTAINS
FUNCTION f ()
character(len=30) :: f
f='Hello Func'
END FUNCTION
END MODULE
Your second problem is linking. Your command:
gfortran hello.for
fails because you did not specify the module object. If you already compiled the module you would specify:
gfortran hello.for func.o
if you were compiling them both at the same time you would do:
gfortran -o hworld func.for hello.for
if you are compiling everything individually:
gfortran -c func.for
gfortran -c hello.for
gfortran -o hworld hello.o func.o
Any of these will compile and run:
% ./hworld
Hello World!
Hello Func
If you are modernizing your code, it would also be worth adding implicit none to avoid any implicit typing and declaring explicit variables for everything. e.g.:
module func
implicit none
contains
function f
implicit none
character(len=30) :: f
f='Hello Func'
end function f
end module func
and
program hello
use func
implicit none
print *, "Hello World!"
print *, f ()
end program hello

using Fortran Module from external files

I would like to call subroutines contained in a module. the module is saved in a separate file with my_mod.f95 filename.
module calc_mean
! this module contains two subroutines
implicit none
public :: calc_sum
public :: mean
contains
subroutine calc_sum(x,n,s)
! this subroutine calculates sum of elements of a vector
! x the vector
! n size of the vector
! s sum of elements of x
integer, intent(in):: n
real, intent(in):: x(n)
integer :: i
real, intent(out):: s
s=0
do i=1,n
s=s+x(i)
end do
end subroutine calc_sum
!
!
!
subroutine mean(x,n,xav)
! this subroutine calculates the mean of a vector
! x the vector
! n size of the vector
! xav mean of x
integer, intent(in):: n
real, intent(in):: x(n)
real, intent(out):: xav
real :: s
!
!
call calc_sum(x,n,s)
xav=s/n
end subroutine mean
end module calc_mean
I have the main program saved in a different file with 'my_program.f95'
program find_mean
! this program calculates mean of a vector
use calc_mean
implicit none
! read the vector from a file
integer, parameter ::n=200
integer :: un, ierror
character (len=25):: filename
real :: x(n), xav
un=30
filename='randn.txt'
!
OPEN (UNIT=un, FILE=filename, STATUS='OLD', ACTION='READ', IOSTAT=ierror)
read(un,*) x !
!
call mean(x,n,xav)
write (*,100) xav
100 format ('mean of x is', f15.8)
end program find_mean
when I compile the main program with geany, I got the following error message. Please, help me!
**
/usr/bin/ld: /tmp/cctnlPMO.o: in function MAIN__': my_program.f08:(.text+0x1e1): undefined reference to __calc_mean_MOD_mean'
collect2: error: ld returned 1 exit status
**
When I save both the main program and the module to the same file and run it, everything is fine.

gfortran, DLL and nothing making sense (or working) at all [duplicate]

This question already has answers here:
Fortran functions returning unexpected types and values
(3 answers)
Closed 2 years ago.
I have the following short piece of code in Fortran, which I named myDLL.f90:
Real(Kind=8) Function mySinCos(x,y)
Real(Kind=8), Intent(In) :: x, y
mySinCos = Sin(x)*Cos(y)
End Function mySinCos
Real(Kind=8) Function myPiSinCos(x,y)
Real(Kind=8), Intent(In) :: x, y
Real(Kind=8), Parameter :: Pi = 4.0d0*Datan(1.0d0)
myPiSinCos = Sin(Pi*x)*Cos(Pi*y)
End Function myPiSinCos
And the following main program TestDLL.f90:
Program TestDLL
Real(Kind=8) :: x, y
Real(Kind=8) :: a, b
x = 2.0d-01
y = 9.0d-01
a = mySinCos(x,y) !Should be 0.12349483641187213
b = myPiSinCos(x,y) !Should be -0.5590169943749475
Write(*,*) a
Write(*,*) b
End Program TestDLL
I compiled and linked the above sources with:
gfortran -shared -fPIC -o myDLL.dll myDLL.f90
gfortran -o a.exe TestDLL.f90 -L. myDLL.dll
No compilation/linkedition errors and a.exe runs without error messages. What it produces is:
6.0000000000000000
6.0000000000000000
Which obviously aren't the expected results as sin(...)*cos(...) must never be > 0.5 (or < -0.5), let alone 6.0000[...].
In a nutshell: compiled well, linked well, executed well and produced garbage.
Changing either x or y doesn't change the results. They're always 6.0000[...].
What went wrong? The example above doesn't differ a lot from other simple examples I've found in the internet.
I'm using GNU Fortran (MinGW.org GCC Build-20200227-1) 9.2.0, Windows 10 64-bit.
It works fine if I turn the two functions into a module:
Module myDLL
Implicit None
Contains
... The two original functions are inserted here ...
End Module myDLL
and import/use the module in the main program:
Program TestDLL
Use myDLL
Implicit None
... Other commands are inserted here ...
End Program TestDLL
Then, and only then, the correct results are spit.

increase array in module

I am trying to write a small module/class in Fortran. The idea is very basic:
Create and initialize the object with a dedicated constructor
Add a new element inside of it
I already write Fortran but only subroutine and I will try to use oriented object principle. Currently I have two errors:
the constructor I built does not work (seems to not accept my input arguments)...
the add_bb procedure is not accepted.
MNWE:
module test_mod
implicit none
type :: bb
real :: item
real,allocatable :: vect(:)
end type bb
interface bb
procedure :: new_bb!,add_bb
end interface bb
contains
type(bb) function new_bb(val,nbv)
real, intent(in) :: val
integer, intent(in) :: nbv
integer :: ii
new_bb%item=val
allocate(new_bb%vect(nbv))
print *,nbv
do ii=1,nbv
new_bb%vect(ii)=val
print *,ii
enddo
print *,new_bb%vect
end function new_bb
type(bb) function add_bb(it)
real,intent(in) :: it
integer :: sp
real,allocatable :: tmp(:)
sp=size(add_bb%vect)+1
allocate(tmp(sp))
tmp(1:sp-1) = add_bb%vect(1:sp-1)
call move_alloc(tmp, add_bb%vect)
add_bb%vect(sp)=it
end function add_bb
end module test_mod
program test
use test_mod
implicit none
type(bb) :: cc
cc=bb(10,20)
call cc%add_bb(10)
print *,cc%item
print *,cc%vect
!
end program test
I tried to fix the bugs in your code, but as I worked on it more, I discovered more and more fundamental flaws in your code. Obviously, that implies that you are likely not well familiar with OOP, in particular, in Fortran. Therefore, I recommend you to grab a book, for example, "Modern Fortran Explained" by Metcalf et al. and learn this topic. Meanwhile, here is a revised version of your code that at least works without syntax error:
module test_mod
implicit none
type :: bb_type
real :: item
real, allocatable :: vect(:)
contains
procedure, pass :: add_bb
end type bb_type
interface bb_type
procedure :: construct_bb
end interface bb_type
contains
function construct_bb(val,nbv) result (bb)
real, intent(in) :: val
integer, intent(in) :: nbv
type(bb_type) :: bb
integer :: ii
bb%item=val
allocate(bb%vect(nbv))
print *,nbv
do ii=1,nbv
bb%vect(ii)=val
print *,ii
enddo
print *,bb%vect
end function construct_bb
subroutine add_bb(self,it)
class(bb_type), intent(inout) :: self
real,intent(in) :: it
integer :: sp
real, allocatable :: tmp(:)
sp=size(self%vect)+1
allocate(tmp(sp))
!tmp(1:sp-1) = self%vect(1:sp-1)
!call move_alloc(tmp, self%vect)
!self%vect(sp)=it
end subroutine add_bb
end module test_mod
program test
use test_mod
implicit none
type(bb_type) :: cc, dd
cc=bb_type(10,[20])
call dd%add_bb(10.0)
print *,cc%item
print *,cc%vect
!
end program test

Confusion with Fortran submodules and gcc compliation flag -Wuse-without-only

What is the remedy for this gcc Fortran compilation warning?
USE statement at (1) has no ONLY qualifier
The warning occurs when using submodules in gcc 6.0, 6.1, 6.2, and, 7.0.
The full compilation sequence and warning:
$ gfortran -c -Wuse-without-only -o mod_module.o mod_module.f08
$ gfortran -c -Wuse-without-only -o mod_module_sub.o mod_module_sub.f08
mod_module_sub.f08:1:19:
submodule ( mModule ) mSubModule
1
Warning: USE statement at (1) has no ONLY qualifier [-Wuse-without-only]
$ gfortran -c -Wuse-without-only -o demonstration.o demonstration.f08
$ gfortran -o demonstration demonstration.o mod_module.o mod_module_sub.o
$ ./demonstration
this + that = 3.00000000
expected value is 3
Main program (demonstration.f08):
program demonstration
use mModule, only : myType
implicit none
type ( myType ) :: example
example % this = 1.0
example % that = 2.0
call example % adder ( )
write ( *, * ) 'this + that = ', example % other
write ( *, * ) 'expected value is 3'
stop
end program demonstration
Module (mod_module.f08):
module mModule
implicit none
type :: myType
real :: this, that, other
contains
private
procedure, public :: adder => adder_sub
end type myType
private :: adder_sub
interface
module subroutine adder_sub ( me )
class ( myType ), target :: me
end subroutine adder_sub
end interface
end module mModule
Submodule (mod_module_sub.f08):
submodule ( mModule ) mSubModule ! <=== problematic statement
implicit none
contains
module subroutine adder_sub ( me )
class ( myType ), target :: me
me % other = me % this + me % that
end subroutine adder_sub
end submodule mSubModule
That is, what is the proper way to specify submodules? The flag -Wuse-without-only is essential in compilation of longer codes.
Depending on your perspective, it is just a compiler bug. File a bug report and wait for it to get fixed (or fix it yourself).
(An alternative perspective is that because that code gives submodules access to all the entities of their host, whether required or not, the warning is appropriate. But limiting host association requires F2015 support.)
-Wuse-without-only is just a warning to help enforce a particular programming style (one that I don't think is particularly useful). It cannot be "essential" to compile any code, short or long. If the warning bothers you in the meantime, remove that option.