Laurent
Laurent

Reputation: 101

Fortran function specifying size of input and output arrays and gfortran bounds check

Let's assume I have the following fortran program

program foobar
implicit none

interface
    pure function foo (var1, var2) result(ans)
        implicit none
        integer, dimension(:),          intent(in) :: var1
        integer, dimension(size(var1)), intent(in) :: var2
        integer, dimension(product(var1 + var2)) :: ans
    end function foo

    pure function bar (n, var1, var2) result(ans)
         implicit none
         integer,                        intent(in) :: n
         integer, dimension(:),          intent(in) :: var1
         integer, dimension(size(var1)), intent(in) :: var2
         integer, dimension(n)                      :: ans
   end function bar
end interface

write (*,*) foo([1, 1, 1], [2, 2, 2])
! write (*,*) bar(27, [1, 1, 1], [2, 2, 2])   
end program foobar

pure function foo (var1, var2) result(ans)
     implicit none
     integer, dimension(:),          intent(in) :: var1
     integer, dimension(size(var1)), intent(in) :: var2
     integer, dimension(product(var1 + var2))   :: ans
     ans = 0
end function foo

pure function bar (n, var1, var2) result(ans)
     implicit none
     integer,                        intent(in) :: n
     integer, dimension(:),          intent(in) :: var1
     integer, dimension(size(var1)), intent(in) :: var2
     integer, dimension(n) :: ans
     ans = 0
end function bar

If I compile this code with

gfortran -fcheck=all -o bbb bbb.F08

then I get the following error during execution

Fortran runtime error: Array bound mismatch for dimension 1 of array 'var2' (0/3)

If I omit the -fcheck=all option, the code compiles and runs just fine. If I comment the first write in the main program and uncomment the second one, the code compiles and runs fine, regardless of whether I use the -fcheck=all option. I couldn't check with other compilers, since gfortran is the only one that I have access to at the moment.

As far as I understand, the compiler cannot determine the size of the array and therefore the check fails during runtime. Is this interpretation correct? Secondly, is there some rule as to what I may place inside dimension() declarations, such that the compiler can still do some bounds checking at runtime? Should I always pass explicitly the size of an array? That way I could probably get around these issues, but it would make calling these functions quite cumbersome.

Upvotes: 1

Views: 1289

Answers (2)

francescalus
francescalus

Reputation: 32366

First, to answer what can be in a dimension declaration for your result variable ans.

ans is an explicit-shape array, so the bound you provide must be a specification expression. Because it is a result variable it needn't be a constant expression, just a restricted expression. Details of how a restricted expression is made up are given in Fortran 2008 7.1.11.

Let's look at the things that make up the expression product(var1 + var2). If that's a restricted expression, you're fine to use it as you have.

var1 and var2 are dummy variables without the intent(out) and optional attributes. So that's good. What's next?

+ here is the intrinsic operation. Tick. Making var1+var2 a restricted expression.

product is a standard intrinsic function which is not a specification inquiry function, and it has argument a restricted expression, and its result in this case is a scalar integer epxression.

So, all that said: it's fine.

And, as Vladimir F says: it's a compiler bug. This just confirms it's not a programmer bug.

Upvotes: 1

This is a compiler bug, already fixed in recent versions. On my computer it fails with gfortran 4.7.and runs OK with pre-release of gfortran-5.

Upvotes: 1

Related Questions