2

I have three pieces of code

  1. Everything in the main.f90 file

    program main
       implicit none
    
       integer, parameter :: N = 10
       real :: x(N), y(N), z(N)
       integer :: i
    
       do i = 1, N
          x(i) = i
          y(i) = 2 * i
       end do
    
       call sum_v(x, y, z)
    
       print *, x
       print *, y
       print *, z
    
    contains
       subroutine sum_v(x, y, z)
          implicit none
    
          real, intent(in) :: x(:), y(:)
          real, intent(out) :: z(:)
    
          integer :: nx, ny, nz
    
          nx = size(x, 1)
          ny = size(y, 1)
          nz = size(z, 1)
    
          if ((nx == ny) .AND. (nx == nz)) then
             z = x + y
          else
             print *, nx, ny, nz
          end if
       end subroutine sum_v
    end program main
    
  2. A main.f90 like: program main implicit none

        integer, parameter :: N = 10
        real :: x(N), y(N), z(N)
        integer :: i
    
        do i = 1, N
           x(i) = i
           y(i) = 2 * i
        end do
    
        call sum_v(x, y, z)
    
        print *, x
        print *, y
        print *, z
    end program main
    

    and a separate file sum.f90

    subroutine sum_v(x, y, z)
       implicit none
    
       real, intent(in) :: x(:), y(:)
       real, intent(out) :: z(:)
    
       integer :: nx, ny, nz
    
       nx = size(x, 1)
       ny = size(y, 1)
       nz = size(z, 1)
    
       if ((nx == ny) .AND. (nx == nz)) then
          z = x + y
       else
          print *, nx, ny, nz
       end if
    end subroutine sum_v
    
  3. Finally, a main.f90 like

    program main
       use v_sum
    
       implicit none
    
       integer, parameter :: N = 10
       real :: x(N), y(N), z(N)
       integer :: i
    
       do i = 1, N
           x(i) = i
           y(i) = 2 * i
       end do
    
       call sum_v2(x, y, z)
    
       print *, x
       print *, y
       print *, z
    end program main
    

    and a sum.f90 like

    module v_sum
       implicit none
    
    contains
       subroutine sum_v(x, y, z)
           implicit none
    
           real, intent(in) :: x(:), y(:)
           real, intent(out) :: z(:)
    
           integer :: nx, ny, nz
    
           nx = size(x, 1)
           ny = size(y, 1)
           nz = size(z, 1)
    
           if ((nx == ny) .AND. (nx == nz)) then
               z = x + y
           else
               print *, nx, ny, nz
           end if
        end subroutine sum_v
    end module v_sum
    

In cases 1 and 3 I observe the correct behavior: a sum of vector is carried out, while in case 2, the other branch of if is take, that is the function is not called correctly. I compile with gfortran using flags -Wall -Wextra -pedantic and no error is given.

three questions

  1. What is going on?
  2. Is there a way to make case 2 work as well without modify the function?
  3. What is the correct way to proceed if one want to compile sum.f90 as as shared library? (what to do with .mod files?)
MaPo
  • 613
  • 4
  • 9
  • 1
    Indeed: cases 1 and 3 which work have an _explicit interface_ available in the main program for the subroutine; case 2 which fails hasn't. An explicit interface is required because the array arguments are assumed shape. While the linked question doesn't go in to much detail, you can search "explicit interface" questions/answer here and get lots, and lots, more to read. – francescalus Jan 27 '22 at 14:39

0 Answers0