How can I make Fortran recognize my function return type?

Viewed 110

I'm learning Fortran and I have to write a function that calculates factorial for a number. Here´s my code:

program functions
    implicit none

    integer :: fact

    fact = factorial(5)
    print *, fact
    
end program functions

recursive function factorial(n) result(factResult)
    implicit none

    integer :: n
    integer :: factResult

    if (n == 0 .or. n == 1) then
        factResult = 1
    else 
        factResult = n * factorial(n - 1)
    end if

end function factorial

I think my code shoud work but I can't compile, I receive this messages when calling factorial(5):

Return type mismatch of function 'factorial' at (1)

(UNKNOWN/INTEGER(4)) Function 'factorial' at (1) has no IMPLICIT type

I don't know what's wrong, it seems than my return type isn't detected. What can I do to make my function work without using intefaces or modules? Because I'm in a basic level.

I'm using Visual Studio Code and I'm compiling with gfortran.

1 Answers

Your main program cannot recognize the factorial() function. Note that even though your function is in the same file as your main program, it does not mean that the main program can automatically find the function. An easy fix to your problem is to extend your main program to contain the function,

program functions
    implicit none

    integer :: fact

    fact = factorial(5)
    print *, fact

contains
    
    recursive function factorial(n) result(factResult)
        implicit none
    
        integer :: n
        integer :: factResult
    
        if (n == 0 .or. n == 1) then
            factResult = 1
        else 
            factResult = n * factorial(n - 1)
        end if
    
    end function factorial

end program functions

Testing it on tutorialspoint online Fortran compiler, your program prints,

120

A better more generic way of fixing the problem would be to put your function in a module, and then use the module in your main program, or anywhere else that may be needed.

module factorial_mod
    
    implicit none

contains
    
    recursive function factorial(n) result(factResult)
        implicit none
    
        integer :: n
        integer :: factResult
    
        if (n == 0 .or. n == 1) then
            factResult = 1
        else 
            factResult = n * factorial(n - 1)
        end if
    
    end function factorial

end module factorial_mod

program functions

    use factorial_mod, only: factorial
    implicit none

    integer :: fact

    fact = factorial(5)
    print *, fact
    
end program functions

Also, keep in mind that the factorial result can grow extremely fast readily causing an integer overflow. You better either use a 64-bit integer to return the result (use iso_fortran_env, only: int64 in your factorial function), or even better, return the natural logarithm of the result (as a real type) instead of the integer value.

Related