Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

type-spec FUNCTION func(...) standard question

38 views
Skip to first unread message

Tobias Burnus

unread,
Sep 1, 2007, 1:43:20 PM9/1/07
to
Hi all,

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

tim prince

unread,
Sep 1, 2007, 3:39:30 PM9/1/07
to
How about

function func1()
integer, parameter :: r8 = kind(0d0)
real(r8) func1

fj

unread,
Sep 1, 2007, 5:29:35 PM9/1/07
to

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

Dick Hendrickson

unread,
Sep 1, 2007, 9:26:37 PM9/1/07
to
Tobias Burnus wrote:
> Hi all,
>
> 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).

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

James Van Buskirk

unread,
Sep 2, 2007, 12:14:18 AM9/2/07
to
"fj" <franco...@irsn.fr> wrote in message
news:1188682175.7...@o80g2000hse.googlegroups.com...

> 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


Message has been deleted

Dick Hendrickson

unread,
Sep 4, 2007, 1:03:02 PM9/4/07
to
John Harper wrote:
> In article <hjoCi.482681$p47.2...@bgtnsc04-news.ops.worldnet.att.net>,

> Dick Hendrickson <dick.hen...@att.net> wrote:
>> Tobias Burnus wrote:
>>> Hi all,
>>>
>>> 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).
>> 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. ...

>>
>> 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
>
> The NAG compiler won't accept case a, saying
> PARAMETER R8 referenced before definition
>
> Neither will g95.

>>> ! Case a
>>> real(r8) function func1()
>>> integer, parameter :: r8 = kind(0d0)
>>> func1 = 0.0_r8
>>> end function func1

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

John Harper

unread,
Sep 4, 2007, 6:00:13 PM9/4/07
to
In article <adgDi.490392$p47.4...@bgtnsc04-news.ops.worldnet.att.net>,
Dick Hendrickson <dick.hen...@att.net> wrote:

>John Harper wrote:
>>
>> The NAG compiler won't accept case a, saying
>> PARAMETER R8 referenced before definition
>>
>> Neither will g95.
>>>> ! Case a
>>>> real(r8) function func1()
>>>> integer, parameter :: r8 = kind(0d0)
...

>
>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."

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!

0 new messages