fortran overloading interface error - overloading

I edit three files
first:add.f90
module MA
implicit none
contains
subroutine show_int(n)
implicit none
integer , intent(in) ::n
write(*,"('n=',I3)") n
return
end subroutine show_int
subroutine show_character(str)
implicit none
character(len=*) ,intent(in) :: str
write(*,"('str=',A)") str
return
end subroutine show_character
end module
second: add.h
interface show
module procedure show_int, show_character
end interface
third:main.f90
program main
use MA
implicit none
include 'add.h'
call show_int(1)
call show(1)
call show_character("Fortran 95")
call show("Fortran 95")
print * ,"hello "
end program
I compile ,gfortran add.f90 main.f90 -o main
I got these errors
add.h:2.2:
包含于 main.f90:4:
module procedure show_int, show_character
1
错误: (1) 语句无法归类
main.f90:6.13:
call show(1)
1
错误: 泛型‘show’在(1)处没有特定的子进程
main.f90:8.24:
call show("Fortran 95") 1
错误: 泛型‘show’在(1)处没有特定的子进程
I don't know why ?
can you help me ?
Thanks

I cannot read the error messages, but:
The module procedure statement can be used only inside the module containing the procedure. Forget the .h file and place the generic interface block into the module. In Fortran 2003 you could use just procedure (without module) and it should work.

Related

How to make sure that all codes in a do statement are executed by one thread using omp_lib in Fortran?

I am using parallel programming to shorten the time for reading data from files in Fortran. The input files are named as a combination of the string and integer with the change of the integer part(for examplefile_1 to file_10). Here is a full minimal example program. the function of the subroutine itoa is to change step number i to character (1 to '1',2 to '2' and so on); name_cre is to combine 'file_' and 'i' to create file name.
MODULE EQUATION
contains
SUBROUTINE itoa(i,res)
INTEGER,INTENT(in) :: i
CHARACTER(len=*),INTENT(out):: res
CHARACTER(range(i)+2) :: tmp
write(tmp,'(i5)') i
res = trim(tmp)
END SUBROUTINE itoa
SUBROUTINE name_cre(f_n,s_n,res)
CHARACTER(len=*),INTENT(in)::f_n,s_n
CHARACTER(len=*),INTENT(out)::res
res = adjustl(trim(f_n))//adjustl(trim(s_n))
END SUBROUTINE name_cre
END MODULE EQUATION
Program read
use equation
USE OMP_LIB
implicit none
integer:: i
integer,dimension(1:10):: step=(/1,2,3,4,5,6,7,8,9,10/)
Character(len = 100):: nu_part,s_name
!$omp parallel do
DO i =1, 10
CALL itoa(step(i),nu_part)
CALL name_cre('file_',nu_part,s_name)
WRITE(*,*) s_name
END DO
!$omp end parallel do
READ(*,*)
END Program read
I want all the statements in one do-loop is executed by one thread, so that the results should be something like
file_1
file_3
file_2
....
or some different orders. But now, it seems that the first CALL is distributed to different thread and the second call is then distributed to another thread so that the results are something like
file_1
file_3
file_3
file_3
....
Thank you all, it seems that both private(i,nu_part,s_name) and !$omp critical can produce similar results I needed. Are there any differences between these two?

Set data breakpoints in GDB for a Fortran executable?

Is it possible to set data breakpoints in GDB to monitor changes of a global variable in a Fortran executable?
Motivation
I am trying to find out, where an unexpected change to a global configuration variable comes from. Source-code based solutions haven't brought up, where any assignment may happen, so I am trying to use GDB. But while I can easily set up break points for subroutine invocations with readline-completion, and then print global and local variables that are in scope, I can't figure out how to set breakpoints for data changes.
I was unable to set data break points for an executable produced with both GFortran and Intel Fortran. It also doesn't help that the Intel documentation for data break points only covers Windows.
Example
For testing purposes I use the following setup:
! persons.f90
module mperson
implicit none
type :: person
integer :: age = 0
character(16) :: name
end type person
type(person), allocatable :: persons(:)
contains
subroutine init_persons(ages, names)
integer, intent(in) :: ages(:)
character(*), intent(in) :: names(:)
integer iPerson
allocate(persons(size(ages)))
do iPerson = 1, size(ages)
persons(iPerson) = person(ages(iPerson), names(iPerson))
end do
end subroutine init_persons
subroutine print_persons()
integer iPerson
print '("-------- print_persons --------")'
do iPerson = 1, size(persons)
print *, persons(iPerson)
end do
persons(2) = person(-1, "undefined") ! <-- This I would like to catch.
end subroutine print_persons
end module mperson
program main
use mperson
implicit none
call init_persons([18,42,13], [character(16)::'Alex', 'Max', 'Bobby Tables'])
call print_persons()
call print_persons()
contains
end program main
Debugged with:
(bash) ifort -g -traceback persons.f90 -o persons.bin
(bash) gdb persons.bin
(gdb) break persons.f90:main
(gdb) run

`Error: Syntax error in OPEN statement` when opening a file for reading

rogram readfromfile
implicit none
integer :: N, i
integer, dimension(130,2) :: cs
OPEN (UNIT=20,FILE='readtry.txt',STATUS='OLD',FORM='UNFORMATTED',)
do i=1,130
read (*,*) cs(i,1), cs(i,2)
enddo
do i=1,130
print *, cs(i,1), cs(i,2)
enddo
I am a beginner in programming, I just want read data from a file which has two columns and approximately 130 lines. I have tried to write down this code but its not working can someone please help?
The following error appears
gfortran -Wall -c "Rwarray.f95" (in directory: D:\Fortrandir\2Darrays)
Rwarray.f95:7:67:
OPEN (UNIT=20,FILE='readtry.txt',STATUS='OLD',FORM='UNFORMATTED',)
1
Error: Syntax error in OPEN statement at (1)
Compilation failed.
you have a compile time error, not a problem reading. But here's the gist of it:
It complains about a syntax error. Your statement is like this:
open(xxx, xxx, xxx, xxx,)
In order for it to compile, you need to remove the last comma. But I don't think that will give you what you want.
When you open the file, you declare it to be unformatted. Unformatted basically means that it contains the values in some form of binary. What's more, unformatted is not guaranteed to work between computers. So unless this file was written on your system, by a Fortran Program, with the FORM="UNFORMATTED" parameter, I don't think you'll get what you want.
I suspect that your input file looks something like this:
1 3
2 10
31 4711
That would be FORMATTED, not UNFORMATTED.
Then you use read(*, *). But the first * in there refers to "standard input", if you want to read from the file, you want to use the read(20, *), as 20 is the unit on which you opened the input file.
For the write statement, the * is correct, assuming that you want to write to "standard output" -- i.e. the screen.
What I'd further recommend is to use the error handling routines. Add these two variables to your declaration block:
integer :: ios
character(len=100) :: iomsg
And then use them whenever you open, read, or write:
open(unit=xx, file=xxx, status=xxx, action=xxx, form=xxx, io_stat=ios, iomsg=iomsg)
call check(ios, iomsg, "OPEN")
read(20, *, io_stat=ios, iomsg=iomsg) cs(1, i), cs(2, i)
call check(ios, iomsg, "READ")
You'd have to include the check subroutine, of course:
program readfromfile
implicit none
<declaraction block>
<execution block>
contains
subroutine check(ios, iomsg, action)
integer, intent(in) :: ios
character(len=*), intent(in) :: iomsg
character(len=*), intent(in), optional :: action
if (ios == 0) return ! No error occured, return
print*, "Error found. Error code:", ios
print*, "Message: ", trim(iomsg)
if (present(action)) print*, "Action was: ", trim(action)
stop 1
end subroutine check
end program readfromfile

Error in fortran, undefined reference to subroutine

I am writing a subroutine and main function to call it, but getting error as undefined reference to ___. I found one reason: When I save the main and subroutine in the same file, compile and run that file, everything runs perfectly. However, when I save them into different .f90 files and try to run the main file, I get error. Is there any way I can make subroutine into a separate file and call into main calling program?
I got confused with another place - in the main program at !------ERROR------ place. I referred to Automatic width integer descriptor in fortran 90 I can use I0 as automatic width display indicator. But when I used the same, there is run time error expected integer but got character. Any idea about this?
! saved as sub_program.f90 file
SUBROUTINE sub_program (v1,v2,ctr)
IMPLICIT NONE
INTEGER, INTENT(IN) :: ctr
INTEGER, INTENT (OUT) :: v1,v2
SELECT CASE (ctr)
CASE (1)
v1=1
v2=0
CASE (2)
v1=0
v2=1
END SELECT
RETURN
END SUBROUTINE
! main calling program, saved as caller.f90
PROGRAM caller
IMPLICIT NONE
INTEGER :: v1,v2,ctr
DO ctr = 1,2,1
CALL sub_program (v1,v2,ctr)
WRITE (*,100) 'STEP = ',ctr,'V1 = ',v1,'V2 = ',v2 !------ERROR------
100 FORMAT (I0)
END DO
END PROGRAM
Thanks!
What is your compile command? For me, this compiles and runs normally
gfortran caller.f90 foo.f90 && ./a.out
I0 is an integer indicator, but some items following your WRITE statement are character strings. You can try, for example,
100 FORMAT (3(A, I0, 1X))
where 1X refers to a space.
As a note, if formatting is not terribly important and you're only interested in seeing some quick results, you can use the free format output (WRITE(*,*) ...).
EDIT: I had incorrectly referred to FORMAT as obsolete.

Is there a way in Fortran to write to an output file from subroutine when the file has open statement in main program.

In Fortran, I am trying to write to an output file from subroutine when the file has open statement in the main program. In other words, how do I pass file unit number (terminal number) to subroutine from the main program. Any idea about this is highly appreciated.For example, my code looks like this,
program main1
open(unit=11,file='output.dat')
call subroutine1
...
call subroutine1
...
end program main1
subroutine subroutine1
write(11,*)'dummy'
...
write(11,*)'dummy'
...
end subroutine subroutine1
By passing the integer representing the opened file:
module mod1
implicit none
contains
subroutine subroutine1(fp)
integer, intent(in) :: fp
write(fp,*)'dummy'
write(fp,*)'dummy'
end subroutine subroutine1
end module mod1
program main1
use mod1
implicit none
integer :: fp
fp = 11
open(unit=fp,file='output.dat')
call subroutine1(fp)
close(fp)
end program main1