which of the following FUNCTION statements is valid and do I extract
this from the Fortran (95 or 2003) standard?
Many compilers seem to to accept (b) and (c), but reject (a).
Tobias
! Case a
real(r8) function func1()
integer, parameter :: r8 = kind(0d0)
func1 = 0.0_r8
end function func1
! Case b
module mod1
integer, parameter :: r8 = kind(0d0)
end module mod1
real(r8) function func2()
use mod1, only: r8
func2 = 0.0_r8
end function func2
! Case c
module mod2
integer, parameter :: r8 = kind(0d0)
interface
real(r8) function func3()
import :: r8
end function func3
end interface
end module mod2
end
Yes this last version always works ... But like Tobias, I don't
understand why the case a) fails to compile with usuals compilers like
g95, gfortran or ifort for instance. From my point of view the case a)
and the last example are stricktly equivalent.
The only explanation seems to be the fact that "r8" is used before
defined ... but the same remark could apply on the case c), the
instruction "import r8" being after the first use of "r8".
Has somebody a good explanation ?
FJ
I believe case a is also valid. I think you "extract" it from
7.1.7 of F2003 or 7.1.6.1 of F95, where initialization expressions
are defined and from 12.5.2.1 of F2003 and 12.5.2.2 of F95 where
functions are defined. I put "extract" in quotes because nothing in
the sections prohibits that way of doing things. I believe that
in F90 (or maybe F95) the decision was made to allow declarations
to be "out of order". The only remaining restriction I could find
about ordering was the one at the end 7.1.7 (and similar in F95)
that requires things to be not out of order in the same statement.
Not prohibiting them is an awkward way to describe features, but it's
what usually happens.
As a rule of thumb in cases like this, try the Nag compiler. It'll
be correct far more often than it's incorrect when it comes to
declaration syntax.
Dick Hendrickson
> Has somebody a good explanation ?
Almost by definition, no. At least the f95 standard is buggy
regarding the position of the type-spec in the FUNCTION statement
within the other specification statments for that function.
Consider the example:
! File: contradict.f90
! Public domain 2007 James Van Buskirk
module mod1
implicit none
contains
function fun()
implicit character(ieor(ieor(kind(1.0),kind(1.0d0)),kind(fun))) (g)
implicit real(len(g1)) (f)
g1 = 'f'
fun = 1
end function fun
end module mod1
program test
use mod1
implicit none
write(*,*) fun()
end program test
! End of file: contradict.f90
The point of the example is that we are trying to pick up the
type and type parameters of FUN from the implicit typing rules
in force within the function subprogram. Those are created on
the line:
implicit real(len(g1)) (f)
Now, we got the type of g1 from a prior IMPLICIT statement:
implicit character(ieor(ieor(kind(1.0),kind(1.0d0)),kind(fun))) (g)
And fun has already been impicitly declared in the FUNCTION statement
itself. The result of these declarations is a cyclic dependency. If
the compiler doesn't like the above, what if the specification-part is
changed to:
implicit character(kind(fun)) (g)
implicit real(kind(1.0)) (f)
This should be OK, right? Well, ifort doesn't like either form but
doesn't yield a legible error message either, and the fault in my
opinon lies in the standard, because it doesn't clearly order the
type-spec in the FUNCTION statement relative to the other specification
statements within the function. Maybe f03 fixes this, but I doubt it.
--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end
I found the true answer (by asking Malcolm Cohen of NAG).
It's illegal.
From 5.2.1.10 PARAMETER attribute,
"A named constant shall not be referenced unless it has been defined
previously in the same statement, defined in a prior statement, or
made accessible by use or host association."
USE and HOST association are special cased, ordinary definition isn't.
Sorry for the confusion.
Dick Hendrickson
>
> You may of course put the declaration of func1 after CONTAINS with the
> declaration of r8 before it, and then you don't need to write your own
> explicit interface, e.g. this complete program. (I use explicit formats
> in test programs because finding differences between outputs is a good
> bughunting method, but various standard-conforming compilers give
> various different outputs for the same real number with * format.)
>
> PROGRAM testr8
> integer, parameter :: r8 = kind(0d0)
> print "(A,ES9.2)", 'Is func1() 0.00E+00 ? ',func1()
> CONTAINS
> real(r8) function func1()
> func1 = 0.0_r8
> end function func1
> END PROGRAM testr8
>
> -- John Harper, School of Mathematics, Statistics and Computer Science,
> Victoria University, PO Box 600, Wellington 6140, New Zealand
> e-mail john....@vuw.ac.nz phone (+64)(4)463 5341 fax (+64)(4)463 5045
That's actually F2003 5.1.2.10 not 5.2.1.10. Equivalent wording
is in F95 5.1.2.1. Thanks to Dick and Malcolm for the information!