Yasir Ahmed
Yasir Ahmed

Reputation: 1

Undefined reference to a function in a module

I was going through all the other threads about undefined reference and I was unable to figure out why this piece of codes is not working. I am basically trying to run a function from a module into a subroutine in the main program. But I keep getting an error

Main:

    program main
        use m1
        implicit none
        integer, dimension(:,:), allocatable :: A,AFun
        integer :: n,i,j
        print *, "enter value for n"
        read *, n
        do i=1,n
                do j=1,n
                        A(i,j)=i**2-j**3
                end do
        end do
        print *, "Matrix A: "
        call prMat(A,n)
        call matFun(A,AFun,n)
        print *, "Matrix AFun:"
        call prMat(AFun,n)
        call fromAvg(AFun,n)

        contains
        subroutine prMat(x,n)
                implicit none
                integer, dimension(n,n) :: x
                integer :: i,j,n
                do i=1,n
                        write(*,*), (x(i,j))
                end do
        end subroutine prMat


        subroutine matfun(x,y,n)
                implicit none
                integer, dimension(n,n) :: x,y
                integer :: i,j,n,f1
                do i = 1,n
                        do j=1,n
                                y(i,j)=f1(x,i,j,n)
                        end do
                end do

        end subroutine matFun
    subroutine fromAvg(x,n)

            integer, dimension(:,:) :: x
            integer :: i,j,n
            integer :: s,avg,g,b
            s=0; g=0; b=0
            do i=1,n
                    do j=1,n
                            s=s+x(i,j)
                    end do
            end do
            avg=s/(n*n)

            do i = 1,n
                    do j = 1,n
                            if ( x(i,j) > avg ) then
                                    g =  g + 1
                            else
                                    b = b + 1
                            end if
                    end do
            end do


            print *, "In from avg, average=", avg
            print *, "Number of values greater than average is ",g
            print *, "Number of values less than average is ",b
    end subroutine fromAvg

        integer, dimension(:,:), allocatable, intent(IN) :: x
        integer :: i,j,n
        integer :: s,avg,g,b
        s=0; g=0; b=0
        do i=1,n
                do j=1,n
                        s=s+x(i,j)
                end do
        end do
        avg=s/(n*n)

        do i = 1,n
                do j = 1,n
                        if ( x(i,j) > avg ) then
                                g =  g + 1
                        elseif ( x(i,j) < avg ) then
                                b = b + 1
                        end if
                end do
        end do


        print *, "In from avg, average=", avg
        print *, "Number of values greater than average is ",g
        print *, "Number of values less than average is ",b
end subroutine fromAvg

end program main

Module Function:

module m1
implicit none
private
public :: f1
contains
function f1(x,p,q,n)
        integer, dimension(:,:) :: x
        integer, intent(in) :: p,q,n
        integer :: i,f1
        f1=0
        do i = 1,n
                f1 = f1 + x(p,n)
        end do
        do i = 1,n
                f1 = f1 + x(n,q)
        end do

end function f1
end module m1

The error that I keep getting is as follows:

/tmp/ccKZHw7L.o: In function `matfun.1520':
lab4_b.f90:(.text+0x808): undefined reference to `__m1_MOD_f1'
collect2: ld returned 1 exit status

Am I missing something? I have use m1 in the beginning of my main program before the implicit none statement.

Upvotes: 0

Views: 2521

Answers (1)

High Performance Mark
High Performance Mark

Reputation: 78316

In the subroutine matfun f1 is (re-)declared to be an integer, in the line

        integer :: i,j,n,f1

This effectively masks the module function from sight. Since the code is (correctly) using the module containing f1 it shouldn't also be declared inside the subroutine.

Then my compiler complains that there is no definition for fromavg but I guess you know that.

Upvotes: 2

Related Questions