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

Array argument bounds checking

63 views
Skip to first unread message

Jared Ahern

unread,
Oct 5, 2009, 11:24:59 AM10/5/09
to
Hello all,

I ran into a bug in my code the other day that came down to passing
improperly-sized array arguments: an allocatable array of allocated
size (6,4) was being passed to a dummy argument of assumed-size (4,4),
and it was not detected. This led me to wonder about some details of
array arguments. In general, I would like the compiler to detect all
array size mismatches at compile time or run time. Which of the
following, if any, are considered poor F90+ practice, or may be missed
by the compiler? (Assume all integer arrays, and available F90
interfaces.)

- passing a(6) to dummy d(4) (should fail at compile time?)
- passing a(6) to dummy d(:) (should succeed - must check bounds
explicitly)
- passing a(6) and n==4 to dummies d(m) and m (should fail at run
time?)
- passing a(6) and b(13) to dummies d(:) and e(2*size(d)) (should fail
at run time?)
- same as all above but with a and/or b allocatable
- any effects of passing array sections
- any other cases that are important to note

Essentially, I'd like to know if I should be able trust the automatic
bounds-checking in all instances, or whether I should just make all
array arguments assumed-shape with explicit size/bound checking. I'm
just not totally clear on the bounds-checking differences among
assumed-shape dummy arrays, automatic arrays, assumed-size dummy
arrays, and fixed-length dummy arrays (any others?). I may have
missed some cases too, so any comments in this area are appreciated; I
do avoid the old F77 a(*) and a(1) dummy arguments.

I've looked through http://orion.math.iastate.edu/burkardt/papers/fortran_arrays.html
and MRC 95/2003, but still wasn't quite clear on what errors gets
caught (or which calling methods aren't errors).

Thanks!
Jared

Richard Maine

unread,
Oct 5, 2009, 11:48:02 AM10/5/09
to
Jared Ahern <jared...@gmail.com> wrote:
[about array argument mismatches]

First, I'll note that I'm assuming you are always talking here about
passing the arrays declared with the dimensions shown - not passing an
array element (which is what would literally happen if you "pass a(6)").
Passing array elements has historical.... complications.

> - passing a(6) to dummy d(4) (should fail at compile time?)

No. That's actually legal. It just passes the first 4 elements of
theactual argument.

> - passing a(6) to dummy d(:) (should succeed - must check bounds
> explicitly)

I don't know what you man by "must check bounds explicitly." The
compiler certainly isn't required to do any such "checking"; there isn't
any for it to do.

> - passing a(6) and n==4 to dummies d(m) and m (should fail at run
> time?)

That's illegal, but no, the compiler is not likely to tell you about it.
Most won't. You will just get strange behavior, possibly including
overwriting memory.

> - passing a(6) and b(13) to dummies d(:) and e(2*size(d)) (should fail
> at run time?)

No. That's legal, just like your first case.

> - same as all above but with a and/or b allocatable

Makes no difference.

> - any effects of passing array sections

Makes no diference.

> Essentially, I'd like to know if I should be able trust the automatic
> bounds-checking in all instances,

Absolutely not. You cannot trust compilers to check such bounds for you
*AT ALL*. Most don't.

> or whether I should just make all
> array arguments assumed-shape with explicit size/bound checking.

That's my recommendation.

> I'm
> just not totally clear on the bounds-checking differences among
> assumed-shape dummy arrays, automatic arrays, assumed-size dummy
> arrays, and fixed-length dummy arrays (any others?).

It is pretty simple, really. Oh, array passing can be complicated, but
what you can assume about checking of argument sizes is simple. Namely,
there is no checking of array argument sizes ever required by the
standard. Some compilers do it in some cases, but it isn't actually
particularly common. You certainly canot count on it. It isn't even
illegal to pass a larger array to a smaller explicit-shape dummy, so you
even more surely can't count on a compiler catching that; in fact, it
would be a compiler bug if it failed to allow that.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain

Ian

unread,
Oct 5, 2009, 11:58:28 AM10/5/09
to
Our book has an appendix (h) on recommended compiler options
at both compile time and run time.

we provide details for

compaq visual fortran
intel
lahey
nag
salford

The Polyhedron site has compiler comparision tables.

Win32 Fortran Compiler Comparisons - Diagnostic Capabilities
http://www.polyhedron.com/pb05-win32-diagnose0html

linux
http://www.polyhedron.com/pb05-linux-diagnose0html

our web site is

http://www.fortranplus.co.uk/

diagnosing and catching errors is very much
a quality of implementation issue.
as you can see from the polyhedron tables
nag and lahey do very well under linux
and salford/silverfrost, lahey and nag do
very well under windows.

p.s. the nag compiler only appears
in the linux table, but is available
under windows as the Fortran Builder product.

hope this helps.

ian chivers

> I've looked throughhttp://orion.math.iastate.edu/burkardt/papers/fortran_arrays.html

James Van Buskirk

unread,
Oct 5, 2009, 12:00:53 PM10/5/09
to
"Jared Ahern" <jared...@gmail.com> wrote in message
news:3650826e-716b-46cb...@k26g2000vbp.googlegroups.com...

> - passing a(6) to dummy d(4) (should fail at compile time?)
> - passing a(6) to dummy d(:) (should succeed - must check bounds
> explicitly)
> - passing a(6) and n==4 to dummies d(m) and m (should fail at run
> time?)
> - passing a(6) and b(13) to dummies d(:) and e(2*size(d)) (should fail
> at run time?)

These are all in fact standard-conforming. The rules of sequence
association allow for them.

--
write(*,*) transfer(0.64682312090346863D-153,(/'X'/));end


The Star King

unread,
Oct 5, 2009, 12:02:08 PM10/5/09
to
On Oct 5, 4:24 pm, Jared Ahern <jared.ah...@gmail.com> wrote:
> Hello all,
>
> I ran into a bug in my code the other day that came down to passing
> improperly-sized array arguments: an allocatable array of allocated
> size (6,4) was being passed to a dummy argument of assumed-size (4,4),
> and it was not detected.  This led me to wonder about some details of
> array arguments.  In general, I would like the compiler to detect all
> array size mismatches at compile time or run time.  Which of the
> following, if any, are considered poor F90+ practice, or may be missed
> by the compiler?  (Assume all integer arrays, and available F90
> interfaces.)
>
> - passing a(6) to dummy d(4) (should fail at compile time?)

real a(6)
call foo(a)
:
end

subroutine foo(a)
real a(4)
end subroutine foo

This is legal. In foo, a is a rank 1 array of size 4. You can access a
(1), a(2) up to a(4) but DON'T try accessing a(5) or a(6)

If you add an interface in the main program, the compiler might warn
you of the mismatch. But it cannot issue an error.

> - passing a(6) to dummy d(:) (should succeed - must check bounds
> explicitly)

real a(6)
call foo(a)
:
end

subroutine foo(a)
real a(:)

n=size(a,1) ! now we know how big it is. only access a(1) to a
(n)
end subroutine foo


> - passing a(6) and n==4 to dummies d(n) and n (should fail at run
> time?)

real a(6)
n=4
call foo(a,n)
:
end

subroutine foo(a,n)
real a(n)
end subroutine foo

legal. But again, you must only access a(1) to a(4)

> - passing a(6) and b(13) to dummies d(:) and e(2*size(d)) (should fail
> at run time?)

real a(6), b(13)
call foo(a,b)
:
end

subroutine foo(d,e)
real d(:),e(2*size(d))
end subroutine foo

Legal but you cannot access e(13).

Basically, the error occurs when you try to access an element you
shouldn't. Using INTERFACES of putting subs in modules may help the
compiler but you cannot rely on it giving warnings. I always run with -
fbounds-check (works on g95 and gfortran)

steve

unread,
Oct 5, 2009, 1:12:35 PM10/5/09
to
On Oct 5, 8:48 am, nos...@see.signature (Richard Maine) wrote:

> Jared Ahern <jared.ah...@gmail.com> wrote:
>
> [about array argument mismatches]
>
> First, I'll note that I'm assuming you are always talking here about
> passing the arrays declared with the dimensions shown - not passing an
> array element (which is what would literally happen if you "pass a(6)").
> Passing array elements has historical.... complications.
>
> > - passing a(6) to dummy d(4) (should fail at compile time?)
>
> No. That's actually legal. It just passes the first 4 elements of
> theactual argument.
>

(snip)

>
> > - passing a(6) and n==4 to dummies d(m) and m (should fail at run
> > time?)
>
> That's illegal, but no, the compiler is not likely to tell you about it.
> Most won't. You will just get strange behavior, possibly including
> overwriting memory.

I suppose I may be misinterpreting what Jared has asked. I read
he's statement as

program z
implicit none
integer a(6), n
a = 1
n = 4
call foo(a,n)
end program z

subroutine foo(d,m)
implicit none
integer d(m), m
print *, d
end subroutine foo

This would appear to be legal based on 12.4.1.4 of the F95 standard.
I, of course, could be misinterpreting the standard, which I've been
known to do in the past.

--
steve

Jared Ahern

unread,
Oct 5, 2009, 1:26:09 PM10/5/09
to
On Oct 5, 11:48 am, nos...@see.signature (Richard Maine) wrote:
> > - passing a(6) to dummy d(4) (should fail at compile time?)
>
> No. That's actually legal. It just passes the first 4 elements of
> the actual argument.

Ah, I didn't realize that. I assumed that the actual and dummy
arguments would have to match in all of these cases... good to fix
taht misconception!

> > - passing a(6) to dummy d(:) (should succeed - must check bounds
> > explicitly)
>

> I don't know what you man by "must check bounds explicitly." The
> compiler certainly isn't required to do any such "checking"; there isn't
> any for it to do.

Right - I didn't mean to say that the compiler was required to do
something here. Since I thought that the other cases would actually
check argument conformance, I just meant that if I wanted the same
sort of bounds checking in this case, I must myself do the checking.

> > or whether I should just make all
> > array arguments assumed-shape with explicit size/bound checking.
>

> That's my recommendation.

That was unfortunately my thought as well. I had thought that the
cases I marked as illegal, well, were. There doesn't seem to be much
point in using those forms then for the cases I am concerned with, and
I should just make sure to make all of my arrays assumed-shape and
check them myself.

> > I'm just not totally clear on the bounds-checking differences

> > among [...] arrays.


>
> It is pretty simple, really.

So it seems. I suppose it's just odd to me that a dummy argument with
a specific size is not required to be matched with an actual argument
of the same size. I would think that was the point of array sections
in the call, but perhaps this leads to some situations where
temporaries can be avoided or something.

A follow-up: if I pass array A of size (3,2) to dummy D(2,2), should I
expect to get D to be in memory [A(1,1) A(2,1) A(3,1) A(1,2)], or just
A(1:2,1:2) ?

Thanks everyone for the replies!

The Star King

unread,
Oct 5, 2009, 1:28:05 PM10/5/09
to

Even the recommended method of assumed shape arrays will not save you
from the dreaded segmentation fault

real a(6,10)
call foo(a)
:
end

subroutine foo(a)
real a(:,:)

n=size(a,1)
m=size(a,2)

do i=1,m ! should be i=1,n
do j=1,n
a(i,j)=1+i-j ! will set a(10,6)!!
enddo
enddo

end subroutine foo

So it's up to you to check. however, using explicit interfaces gives
the compiler the ability to do some checking for you. Personally I
would never dare to run a program for the first time without -fbounds-
check (gfortran).

Jared Ahern

unread,
Oct 5, 2009, 1:34:01 PM10/5/09
to
> Personally I
> would never dare to run a program for the first time without -fbounds-
> check (gfortran).

Me neither. My original problem wasn't caught though, with bounds-
checking enabled on g95. Usually I cross-check with different
compilers, but I was compiling against a library with g95 .mod files,
and I didn't want to recompile that at the time.

Message has been deleted

steve

unread,
Oct 5, 2009, 1:46:01 PM10/5/09
to

Of course, you need and explicit interface to have a chance at working
code.

real a(6,10)
interface


subroutine foo(a)
real a(:,:)

end subroutine foo
end interface
call foo(a)
end

glen herrmannsfeldt

unread,
Oct 5, 2009, 2:15:40 PM10/5/09
to
The Star King <j...@npl.co.uk> wrote:
(snip, someone wrote)

<> I ran into a bug in my code the other day that came down to passing
<> improperly-sized array arguments: an allocatable array of allocated
<> size (6,4) was being passed to a dummy argument of assumed-size (4,4),
<> and it was not detected.

As noted, that is perfectly legal, but also confusing. The array
elements associate in the order they are stored in memory, as
required by the standard. The are stored with the leftmost subscript
changing fastest, so the first four work as you might expect, but...

consider a(6,4) in the calling routine and b(4,4) dummy in the
called routine.

The fifth element in memory is a(5,1) associating with b(1,2),
a(6,1) with b(2,2), and a(1,2) with b(3,2). All according
to the standard. Note that it isn't even required, in the
explicit or assumed size case for the rank to match. It is
often done with a rank-1 dummy and explicit calculation of the
offset.

<> This led me to wonder about some details of array arguments.
<> In general, I would like the compiler to detect all

<> array size mismatches at compile time or run time. ?Which of the


<> following, if any, are considered poor F90+ practice, or may be missed

<> by the compiler? ?(Assume all integer arrays, and available F90
<> interfaces.)

<> - passing a(6) to dummy d(4) (should fail at compile time?)

< real a(6)
< call foo(a)
< :
< end

< subroutine foo(a)
< real a(4)
< end subroutine foo

< This is legal. In foo, a is a rank 1 array of size 4. You can access a
< (1), a(2) up to a(4) but DON'T try accessing a(5) or a(6)

Most likely with bounds check turned off access to a(5) and a(6)
would work. As bounds information is not (normally) passed, the
called routine can't check. With bounds checking, the called
routine will (normally) use the dimensions you supply.



< If you add an interface in the main program, the compiler might warn
< you of the mismatch. But it cannot issue an error.

<> - passing a(6) to dummy d(:) (should succeed - must check bounds
<> explicitly)

< real a(6)
< call foo(a)
< :
< end

< subroutine foo(a)
< real a(:)
<
< n=size(a,1) ! now we know how big it is. only access a(1) to a
< (n)
< end subroutine foo

Yes. The advantage of assumed shape is that you can write a
subroutine that will work for any size array.

<> - passing a(6) and n==4 to dummies d(n) and n (should fail at run
<> time?)

< real a(6)
< n=4
< call foo(a,n)
< :
< end

< subroutine foo(a,n)
< real a(n)
< end subroutine foo

< legal. But again, you must only access a(1) to a(4)

Specifically, it is not uncommon to want to operate on
part of an array.


<> - passing a(6) and b(13) to dummies d(:) and e(2*size(d))
<> (should fail at run time?)

< real a(6), b(13)
< call foo(a,b)
< :
< end

It is probably best not to mix assumed shape with other methods.
Make them both assumed shape and check size() yourself.



< subroutine foo(d,e)
< real d(:),e(2*size(d))
< end subroutine foo

< Legal but you cannot access e(13).

In the Fortran 66 days it was common to dimension the dummy
array (1), (even for rank higher than one) and explicitely
calculate the offset. With Fortran 77, the * was added to
specifically tell the compiler that is what you were doing.

Many compilers, even with bounds check off, will notice at
compile time constant subscripts that are outside the
specified bounds. That has complicated porting Fortran 66
code using the (1) method.

-- glen

glen herrmannsfeldt

unread,
Oct 5, 2009, 2:57:07 PM10/5/09
to
Jared Ahern <jared...@gmail.com> wrote:
< On Oct 5, 11:48 am, nos...@see.signature (Richard Maine) wrote:
<> > - passing a(6) to dummy d(4) (should fail at compile time?)

<> No. That's actually legal. It just passes the first 4 elements of
<> the actual argument.

< Ah, I didn't realize that. I assumed that the actual and dummy
< arguments would have to match in all of these cases... good to fix
< taht misconception!

For most of the years that Fortran has been available, there
were no dynamic arrays. (At least from 1956 to 1990. When did
an actual Fortran 90 compiler first appear?)

The solution was to dimension arrays to the largest problem
that might ever appear, within the limits of available memory.
(On a single task system, you might as well use it.)

The abilty to pass a larger array than actually needed was,
then, very important. For higher than rank one, you need to pass
both the actual dimension of the array and the dimension of the
part you actually want to use.

Also, it used to be common to have matrix routines that would
operate on triangular matrices, and other special types.
As Fortran has no support for a triangular matrix, it was
all done computing offsets into a rank one array.

-- glen

Jared Ahern

unread,
Oct 5, 2009, 3:23:53 PM10/5/09
to
On Oct 5, 2:57 pm, glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
> For most of the years that Fortran has been available, there
> were no dynamic arrays.  (At least from 1956 to 1990.  When did
> an actual Fortran 90 compiler first appear?)

I've had to deal with calling some F77-style routines, but in general,
I've been able to avoid them; although I do recall seeing some tricks
where you change the rank of the array being passed. But I thought
that one of the points of having F90 explicit interfaces was to
communicate the dummy argument bound information to the caller, at
least in some cases. Also, they can tell the caller how to pass
actual argument bound information to the callee. It always seemed
clear to me that you use interfaces/modules to maintain array sizes,
and avoid using them if you really wish to pass a larger actual array
into a smaller dummy one. So much for that idea!

Richard Maine

unread,
Oct 5, 2009, 3:41:31 PM10/5/09
to
Jared Ahern <jared...@gmail.com> wrote:

> So it seems. I suppose it's just odd to me that a dummy argument with
> a specific size is not required to be matched with an actual argument
> of the same size.

What you are missing is the history. That would be incompatible with f77
and everything before... which makes it a non-starter. And for f77,
well... there were lots of reasons why you would not have wanted such a
requirement then, but I'll not try to reconstruct all of those. I'l just
leave it as that's the way it was and there is no way that f90 was going
to be incompatible with it.

And no, having an explicit interface doesn't change things at that
level. Having an explicit interface basically lets the caller know what
the called procedure looks like. If a call was legal before, it is still
legal with an explicit interface (almost always*). It is important to
understand that the calls in question were legal all along. It isn't
just that the compilers didn't have the information to diagnose them;
they were actually legal. So when you add the explicit interface to let
the compiler know what the called procedure looks like, it i still
legal.

*The exceptions are arcane, mostly involving some obscure things that
are basically incompatible with having an explicit interface. The only
one I can think of at the moment is assumed-length character function
results, though it is possible that I might have forgotten some other
even more obscure case.

Richard Maine

unread,
Oct 5, 2009, 3:43:44 PM10/5/09
to
steve <kar...@comcast.net> wrote:

> On Oct 5, 8:48 am, nos...@see.signature (Richard Maine) wrote:
> > Jared Ahern <jared.ah...@gmail.com> wrote:

> > > - passing a(6) and n==4 to dummies d(m) and m (should fail at run
> > > time?)
> >

> > That's illegal...

> This would appear to be legal...

Oops. You are right. I somewhat hastily got it backwards, thinking that
he was passing an actual of size 4 to a dummy of size 6 instead of the
other way around.

Richard Maine

unread,
Oct 5, 2009, 3:45:16 PM10/5/09
to
I forgot to answer this part. Skipped over it down there.

Jared Ahern <jared...@gmail.com> wrote:

> A follow-up: if I pass array A of size (3,2) to dummy D(2,2), should I
> expect to get D to be in memory [A(1,1) A(2,1) A(3,1) A(1,2)],

Yes.

> or just A(1:2,1:2) ?

No.

nm...@cam.ac.uk

unread,
Oct 5, 2009, 3:59:44 PM10/5/09
to
In article <1j745ho.ft3f4uqdvkhkN%nos...@see.signature>,

Richard Maine <nos...@see.signature> wrote:
>
>And no, having an explicit interface doesn't change things at that
>level. Having an explicit interface basically lets the caller know what
>the called procedure looks like. If a call was legal before, it is still
>legal with an explicit interface (almost always*). It is important to
>understand that the calls in question were legal all along. It isn't
>just that the compilers didn't have the information to diagnose them;
>they were actually legal. So when you add the explicit interface to let
>the compiler know what the called procedure looks like, it i still
>legal.
>
>*The exceptions are arcane, mostly involving some obscure things that
>are basically incompatible with having an explicit interface. The only
>one I can think of at the moment is assumed-length character function
>results, though it is possible that I might have forgotten some other
>even more obscure case.

Alternate return?


Regards,
Nick Maclaren.

Richard Maine

unread,
Oct 5, 2009, 4:16:38 PM10/5/09
to
<nm...@cam.ac.uk> wrote:

> In article <1j745ho.ft3f4uqdvkhkN%nos...@see.signature>,
> Richard Maine <nos...@see.signature> wrote:

> >If a call was legal before, it is still
> >legal with an explicit interface (almost always*).

> >*The exceptions are arcane, mostly involving some obscure things that


> >are basically incompatible with having an explicit interface. The only
> >one I can think of at the moment is assumed-length character function
> >results, though it is possible that I might have forgotten some other
> >even more obscure case.
>
> Alternate return?

Good guess in that it is an obscure case that I didn't think of. I
certainly have never ever tried it, and I only quickly skimmed, but I
think alternate returns are ok with explicit interfaces. I don't
off-hand recall a prohibition. And alternate returns are still
technically in the language, although on the obsolescent list.

James Van Buskirk

unread,
Oct 5, 2009, 5:01:39 PM10/5/09
to
"Richard Maine" <nos...@see.signature> wrote in message
news:1j747cu.ws6k9ctvxox0N%nos...@see.signature...

> <nm...@cam.ac.uk> wrote:

>> In article <1j745ho.ft3f4uqdvkhkN%nos...@see.signature>,
>> Richard Maine <nos...@see.signature> wrote:

>> >If a call was legal before, it is still
>> >legal with an explicit interface (almost always*).

>> >*The exceptions are arcane, mostly involving some obscure things that
>> >are basically incompatible with having an explicit interface. The only
>> >one I can think of at the moment is assumed-length character function
>> >results, though it is possible that I might have forgotten some other
>> >even more obscure case.

>> Alternate return?

> Good guess in that it is an obscure case that I didn't think of. I
> certainly have never ever tried it, and I only quickly skimmed, but I
> think alternate returns are ok with explicit interfaces. I don't
> off-hand recall a prohibition. And alternate returns are still
> technically in the language, although on the obsolescent list.

I think the alternate return stuff is busted by N1601.pdf, C1205:

"(R1205) An interface-body of a pure procedure shall specify the intents of
all dummy arguments except pointer, alternate return, and procedure
arguments."

You wouldn't need that clause about alternate returns unless a
procedure given in an interface-body could have them.

Also C418 is interesting:

"A function name declared with an asterisk type-param-value shall not be an
array, a pointer, recursive, or pure."

There are other things that require an explicit interface, so we may assumed
that an explicit interface is not out of the question for functions with
assumed-length results. Time for an example:

C:\gfortran\clf\nonexplicit>type nonexplicit.f90
module funcs
implicit none
integer, parameter :: dp = kind([double precision :: ])
interface
function assumed_len(x)
character(5) assumed_len
integer, intent(in) :: x
end function assumed_len
end interface
contains
subroutine alt(n,x,*,*)
integer n
real(dp) x
entry another(x,*,n,*)
if(n == 1) then
x = 13
return 1
else
x = 17
return 2
end if
end subroutine alt
end module funcs

program test
use funcs
implicit none
character(6) x(3)
integer i
real(dp) y

do i = 1, size(x)
x(i) = assumed_len(x=i)
end do
write(*,'(a/(a))') 'x = ', x
call alt(1,y,*10,*100)
write(*,'(a)') 'Bad error'
stop
10 continue
write(*,'(a,f0.1)') 'Should get here. y = ', y
call alt(2,y,*100,*20)
write(*,'(a)') 'Bad error'
stop
20 continue
write(*,'(a,f0.1)') 'Should get here. y = ', y
call another(y,*30,1,*100)
write(*,'(a)') 'Bad error'
stop
30 continue
write(*,'(a,f0.1)') 'Should get here. y = ', y
call another(y,*40,2,*100)
40 write(*,'(a)') 'Bad error'
stop
100 continue
write(*,'(a,f0.1)') 'End of test. y = ', y
end program test

function assumed_len(x)
character(*) assumed_len
integer, intent(in) :: x

assumed_len = repeat(achar(64+modulo(x,32)),len(assumed_len))
end function assumed_len

C:\gfortran\clf\nonexplicit>gfortran -Wall nonexplicit.f90 -ononexplicit

C:\gfortran\clf\nonexplicit>nonexplicit
x =
AAAAA
BBBBB
CCCCC
Should get here. y = 13.0
Should get here. y = 17.0
Should get here. y = 13.0
End of test. y = 17.0

Ron Shepard

unread,
Oct 5, 2009, 5:14:00 PM10/5/09
to
In article <hadfi3$g8o$7...@naig.caltech.edu>,
glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

> Jared Ahern <jared...@gmail.com> wrote:
> < On Oct 5, 11:48 am, nos...@see.signature (Richard Maine) wrote:
> <> > - passing a(6) to dummy d(4) (should fail at compile time?)
>
> <> No. That's actually legal. It just passes the first 4 elements of
> <> the actual argument.

I would describe the actual mechanism a little differently. The address
of a(6) is passed to the subroutine, and this becomes the address of the
first element of the dummy array dimensioned d(4).

> For most of the years that Fortran has been available, there
> were no dynamic arrays. (At least from 1956 to 1990. When did
> an actual Fortran 90 compiler first appear?)

There was a "vast right wing conspiracy" during the decade of the 1980's
that managed to prevent the ANSI committee from passing a new standard.
After f77, the new standard was originally intended to be approved in
about 1983 or 1984. After the first delays, it was anticipated to be
approved in 1988. When it became clear that date would be missed too,
it was common to call the draft standard "fortran 8x". Finally the new
standard was approved in 1991, first internationally by ISO, then only
later by ANSI.

There were fortran compilers that implemented bits and pieces of the
proposed standard all during that time. I used commercial fortran
compilers in 1988 and 1989 that implemented the ALLOCATE and DEALLOCATE
statements from the drafts, but if you were concerned with portability,
you had to be careful because most compilers did not yet do this.

However, there were other nonstandard ways of supporting dynamic arrays
that were common. Many compilers supported a C-like malloc() function,
along with what were called "cray pointers" to associate the address
with an array. Or one could use malloc() along with a %VAL() designator
in a subprogram call to achieve the same kind of association.

So dynamic arrays were available on many (perhaps even most, but not
all) fortran implementations in the decade of the 1980's, but it was, at
best, only part of the proposed standard language because of the failure
of the ANSI committee during that period.

> The solution was to dimension arrays to the largest problem
> that might ever appear, within the limits of available memory.
> (On a single task system, you might as well use it.)
>
> The abilty to pass a larger array than actually needed was,
> then, very important. For higher than rank one, you need to pass
> both the actual dimension of the array and the dimension of the
> part you actually want to use.

I did this during this period in my codes, although your description
above isn't very close to the way I did it. Basically you had to manage
the memory heap/stack yourself, with fortran code, rather than relying
on the compiler and OS to do this for you. You didn't really dimension
everything for the "largest problem", you instead dimensioned an array
that you then treated as a heap, and tried to force your problem to fit
into the available memory. Sometimes this affected how a problem was
divided up into pieces, or even which algorithm you might use for some
step, as one might fit but another would wouldn't, and the program could
decide at runtime which set of branches to take as the program ran.

> Also, it used to be common to have matrix routines that would
> operate on triangular matrices, and other special types.
> As Fortran has no support for a triangular matrix, it was
> all done computing offsets into a rank one array.

This is still common, even with modern fortran. If you consider, for
example, addressing a lower-triangular-packed dense matrix stored by
rows, then accessing a column of such a matrix consists of different
increments between consecutive elements down the column. This is
straightforward to do by computing offsets, and it requires no
additional memory references (not counting the register arithmetic for
the indexing). But if it is done with a fixed offset added to an array
of row pointers, then it doubles the number of memory references. Some
other possible sparse matrix storage schemes are even worse, requiring
three or four times the total number of memory references. For
something like a matrix-vector product which is already memory bandwidth
limited anyway, doubling or tripling the number of memory references is
a killer for this kind of scheme, whether the language "supports" it
directly or the user does it manually.

This is an example of using storage sequence association in a way that
is superior to almost all array indexing schemes that are supported by
high level languages (including fortran's array syntax). It is
unfortunate that languages (apparently) cannot be designed that exploit
this same kind of efficiency. I know that many smart people have looked
at this problem over the years, so I suspect that it just isn't possible
to do any better.

$.02 -Ron Shepard

glen herrmannsfeldt

unread,
Oct 5, 2009, 6:22:31 PM10/5/09
to
Ron Shepard <ron-s...@nospam.comcast.net> wrote:
< In article <hadfi3$g8o$7...@naig.caltech.edu>,
< glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

<> Jared Ahern <jared...@gmail.com> wrote:
<> < On Oct 5, 11:48 am, nos...@see.signature (Richard Maine) wrote:
<> <> > - passing a(6) to dummy d(4) (should fail at compile time?)
>
<> <> No. That's actually legal. It just passes the first 4 elements of
<> <> the actual argument.

< I would describe the actual mechanism a little differently. The address
< of a(6) is passed to the subroutine, and this becomes the address of the
< first element of the dummy array dimensioned d(4).

I think by a(6) he actually meant an array with dimension (6),
probably not at all believing what you can actually do with a(6).



<> For most of the years that Fortran has been available, there
<> were no dynamic arrays. (At least from 1956 to 1990. When did
<> an actual Fortran 90 compiler first appear?)

< There was a "vast right wing conspiracy" during the decade of the 1980's
< that managed to prevent the ANSI committee from passing a new standard.
< After f77, the new standard was originally intended to be approved in
< about 1983 or 1984. After the first delays, it was anticipated to be
< approved in 1988. When it became clear that date would be missed too,
< it was common to call the draft standard "fortran 8x". Finally the new
< standard was approved in 1991, first internationally by ISO, then only
< later by ANSI.

The series 66, 77, 88 made so much sense to me...

Also, I have an actual copy of "Fortran 8x explained".
I believe I bought it used in 1989.

(snip of not-yet-Fortran 90 explanation)



< So dynamic arrays were available on many (perhaps even most, but not
< all) fortran implementations in the decade of the 1980's, but it was, at
< best, only part of the proposed standard language because of the failure
< of the ANSI committee during that period.

I remember VAX/VMS (the source of %VAL) code calling the VAX
system library routines (names with $ in them) to do things like
allocation and I/O.



<> The solution was to dimension arrays to the largest problem
<> that might ever appear, within the limits of available memory.
<> (On a single task system, you might as well use it.)

<> The abilty to pass a larger array than actually needed was,
<> then, very important. For higher than rank one, you need to pass
<> both the actual dimension of the array and the dimension of the
<> part you actually want to use.

< I did this during this period in my codes, although your description
< above isn't very close to the way I did it. Basically you had to manage
< the memory heap/stack yourself, with fortran code, rather than relying
< on the compiler and OS to do this for you. You didn't really dimension
< everything for the "largest problem", you instead dimensioned an array
< that you then treated as a heap, and tried to force your problem to fit
< into the available memory. Sometimes this affected how a problem was
< divided up into pieces, or even which algorithm you might use for some
< step, as one might fit but another would wouldn't, and the program could
< decide at runtime which set of branches to take as the program ran.

Yes, my explanation only works for the case where you need only
one large array. Sometimes it works if you need some number of
similar sized large arrays.


<> Also, it used to be common to have matrix routines that would
<> operate on triangular matrices, and other special types.
<> As Fortran has no support for a triangular matrix, it was
<> all done computing offsets into a rank one array.

< This is still common, even with modern fortran. If you consider, for
< example, addressing a lower-triangular-packed dense matrix stored by
< rows, then accessing a column of such a matrix consists of different
< increments between consecutive elements down the column. This is
< straightforward to do by computing offsets, and it requires no
< additional memory references (not counting the register arithmetic for
< the indexing). But if it is done with a fixed offset added to an array
< of row pointers, then it doubles the number of memory references. Some
< other possible sparse matrix storage schemes are even worse, requiring
< three or four times the total number of memory references. For
< something like a matrix-vector product which is already memory bandwidth
< limited anyway, doubling or tripling the number of memory references is
< a killer for this kind of scheme, whether the language "supports" it
< directly or the user does it manually.

I used to have listings of library routines that would accept different
types (rectangular, triangular, diagonal) depending on the value of
some arguments. They would then compute, sometimes with a function
call, the appropriate offset for the given element and matrix type.
As usual, with dummy arguments dimensioned (1).



< This is an example of using storage sequence association in a way that
< is superior to almost all array indexing schemes that are supported by
< high level languages (including fortran's array syntax). It is
< unfortunate that languages (apparently) cannot be designed that exploit
< this same kind of efficiency. I know that many smart people have looked
< at this problem over the years, so I suspect that it just isn't possible
< to do any better.

PL/I has the DEFINED attribute that pretty much allows for it, but
I believe that DEFINED arrays can't be passed to subprograms.
That makes them somewhat less useful than they otherwise might be.
DEFINED is PL/I's non-symmetric replacement for Fortran EQUIVALENCE.

-- glen

robin

unread,
Oct 5, 2009, 9:53:59 PM10/5/09
to
"glen herrmannsfeldt" <g...@ugcs.caltech.edu> wrote in message news:hadd4c$g8o$3...@naig.caltech.edu...

It can, using the bounds specified in the subroutine, namely, 1:4

robin

unread,
Oct 5, 2009, 9:53:59 PM10/5/09
to
"Richard Maine" <nos...@see.signature> wrote in message news:1j73ud7.uiiuuf1eymtvkN%nos...@see.signature...

| Jared Ahern <jared...@gmail.com> wrote:
| [about array argument mismatches]
|
| First, I'll note that I'm assuming you are always talking here about
| passing the arrays declared with the dimensions shown - not passing an
| array element (which is what would literally happen if you "pass a(6)").
| Passing array elements has historical.... complications.

| > - passing a(6) and n==4 to dummies d(m) and m (should fail at run


| > time?)
|
| That's illegal, but no, the compiler is not likely to tell you about it.
| Most won't. You will just get strange behavior, possibly including
| overwriting memory.

It has been the normal way to pass arrays to subroutines and
functions from time immemorial. It's called "adjustable dimensions")


robin

unread,
Oct 5, 2009, 9:54:00 PM10/5/09
to
"Jared Ahern" <jared...@gmail.com> wrote in message
news:542edc1e-04a4-4095...@d4g2000vbm.googlegroups.com...
+On Oct 5, 2:57 pm, glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
+> For most of the years that Fortran has been available, there
+> were no dynamic arrays. (At least from 1956 to 1990. When did
+> an actual Fortran 90 compiler first appear?)

+I've had to deal with calling some F77-style routines, but in general,
+I've been able to avoid them; although I do recall seeing some tricks
+where you change the rank of the array being passed. But I thought
+that one of the points of having F90 explicit interfaces was to
+communicate the dummy argument bound information to the caller, at
+least in some cases. Also, they can tell the caller how to pass
+actual argument bound information to the callee. It always seemed
+clear to me that you use interfaces/modules to maintain array sizes,
+and avoid using them if you really wish to pass a larger actual array
+into a smaller dummy one. So much for that idea!

That's the idea of interfaces, namely, so that you can pass
arrays and array sections and have them accessed perfectly
in the called procedure. Adjustable dimensions was a scheme
that was error-prone, because there was no checking.


robin

unread,
Oct 5, 2009, 9:54:01 PM10/5/09
to
"Ron Shepard" <ron-s...@NOSPAM.comcast.net> wrote in message
news:ron-shepard-14C2...@news60.forteinc.com...

| In article <hadfi3$g8o$7...@naig.caltech.edu>,
| glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
|
| > Jared Ahern <jared...@gmail.com> wrote:
| > < On Oct 5, 11:48 am, nos...@see.signature (Richard Maine) wrote:
| > <> > - passing a(6) to dummy d(4) (should fail at compile time?)
| >
| > <> No. That's actually legal. It just passes the first 4 elements of
| > <> the actual argument.
|
| I would describe the actual mechanism a little differently. The address
| of a(6) is passed to the subroutine, and this becomes the address of the
| first element of the dummy array dimensioned d(4).

It's clear that the OP meant an array 'a' of dimension 6.
See the 'dummy d(4)' which the OP means array 'd'
dimensioned 4.


robin

unread,
Oct 5, 2009, 9:54:00 PM10/5/09
to
"Richard Maine" <nos...@see.signature> wrote in message news:1j73ud7.uiiuuf1eymtvkN%nos...@see.signature...
| Jared Ahern <jared...@gmail.com> wrote:
| [about array argument mismatches]
|
| First, I'll note that I'm assuming you are always talking here about
| passing the arrays declared with the dimensions shown - not passing an
| array element (which is what would literally happen if you "pass a(6)").
| Passing array elements has historical.... complications.
|
| > - passing a(6) to dummy d(4) (should fail at compile time?)
|
| No. That's actually legal. It just passes the first 4 elements of
| theactual argument.

No, it passes the address of the first element.


robin

unread,
Oct 5, 2009, 9:54:02 PM10/5/09
to
"Jared Ahern" <jared...@gmail.com> wrote in message
news:71f1a01b-1d32-4b04...@33g2000vbe.googlegroups.com...

| On Oct 5, 11:48 am, nos...@see.signature (Richard Maine) wrote:
| > > - passing a(6) to dummy d(4) (should fail at compile time?)
| >
| > No. That's actually legal. It just passes the first 4 elements of
| > the actual argument.
|
| Ah, I didn't realize that.

Maine is wrong. It passes only the address of the first element of the array.
How big the array is is irrelevant, except that the called routine must ensure that
it addresses only legitimate elements of the actual argument.
If it accidentally references elements beyond either end of the array, THAT's an error.
(except if the actual argument is equivalenced with something else
that "extends" the array in one direction or another.)

| I assumed that the actual and dummy
| arguments would have to match in all of these cases... good to fix
| taht misconception!

They don't have to "match", as described above.


Dan Nagle

unread,
Oct 6, 2009, 5:39:44 AM10/6/09
to
Hello,

On 2009-10-05 21:54:00 -0400, "robin" <rob...@bigpond.com> said:

> "Richard Maine" <nos...@see.signature> wrote in message
> news:1j73ud7.uiiuuf1eymtvkN%nos...@see.signature...
> | Jared Ahern <jared...@gmail.com> wrote:
> | [about array argument mismatches]

> | > - passing a(6) to dummy d(4) (should fail at compile time?)


> |
> | No. That's actually legal. It just passes the first 4 elements of
> | theactual argument.
>
> No, it passes the address of the first element.

How any compiler actually implements argument association
is unspecified. A given compiler need not use the same
method in different circumstances.

So long as the rules of argument association are upheld,
how the compiler accomplishes it is the compiler's domain.

Many compilers in many situations will pass an address,
but that's not required, and an application should not
depend upon it.

--
Cheers!

Dan Nagle

robin

unread,
Oct 6, 2009, 11:44:01 AM10/6/09
to
"glen herrmannsfeldt" <g...@ugcs.caltech.edu> wrote in message news:hadfi3$g8o$7...@naig.caltech.edu...

| Jared Ahern <jared...@gmail.com> wrote:
| < On Oct 5, 11:48 am, nos...@see.signature (Richard Maine) wrote:
| <> > - passing a(6) to dummy d(4) (should fail at compile time?)
|
| <> No. That's actually legal. It just passes the first 4 elements of
| <> the actual argument.
|
| < Ah, I didn't realize that. I assumed that the actual and dummy
| < arguments would have to match in all of these cases... good to fix
| < taht misconception!
|
| For most of the years that Fortran has been available, there
| were no dynamic arrays. (At least from 1956 to 1990. When did
| an actual Fortran 90 compiler first appear?)
|
| The solution was to dimension arrays to the largest problem
| that might ever appear, within the limits of available memory.
| (On a single task system, you might as well use it.)
|
| The abilty to pass a larger array than actually needed was,
| then, very important. For higher than rank one, you need to pass
| both the actual dimension of the array and the dimension of the
| part you actually want to use.

No, you needed to pass the array and the bounds of the
"fictitious" array that you wanted to use. The number of dimensions
did not even need to match.

| Also, it used to be common to have matrix routines that would
| operate on triangular matrices, and other special types.
| As Fortran has no support for a triangular matrix, it was
| all done computing offsets into a rank one array.

It was a gimmick to conserve storage, and was done on all early computers,
regardless of language.


Tobias Burnus

unread,
Oct 6, 2009, 11:54:22 AM10/6/09
to
On 10/05/2009 11:01 PM, James Van Buskirk wrote:
> interface
> function assumed_len(x)
> character(5) assumed_len
> integer, intent(in) :: x
> end function assumed_len
> end interface

> function assumed_len(x)


> character(*) assumed_len
> integer, intent(in) :: x
>
> assumed_len = repeat(achar(64+modulo(x,32)),len(assumed_len))
> end function assumed_len


It is not clear to me whether this is valid or not. NAG f95 only allows
it only with an implicit interface such as
external assumed_len
character(5) assumed_len
and not an explicit interface as in the example.

* * *

I found the following bits in the standard but I have problems to draw a
solid conclusion from it.


[General regarding assumed-character-length functions]

"A char-length type parameter value of * has the following meaning: [...]
(4) If used to specify the character length parameter of a function
result, any scoping unit invoking the function shall declare the
function name with a character length parameter value other than * or
access such a definition by host or use association. When the function
is invoked, the length of the result variable in the function is assumed
from the value of this type parameter."
(F2003, 4.4.4.1 Character type specifier)


[Explicit interfaces]

a) "12.2.2 Characteristics of function results": "If the length of a
character function result is assumed, this is a characteristic."

b) "An interface body specifies all of the characteristics of the
explicit specific interface or abstract interface."

c) "If an explicit specific interface is specified by an interface body
or a procedure declaration statement (12.3.2.3) for an external
procedure, the characteristics shall be consistent with those specified
in the procedure definition, except that the interface may specify a
procedure that is not pure if the procedure is defined to be pure."

Thus: assumed character length = characteristic and characteristic shall
be "consistent" (whatever this means exactly).

[Implicit interfaces] -- I only found:

"If a type is specified for an external function, its function
definition (12.5.2.1) shall specify the same result type and type
parameters."


I think at least the implicit interface is allowed as this is a legacy
feature and if neither implicit nor explicit interface were allowed, the
function would not be accessible and thus useless.

Thus the main question is whether an explicit interface is allowed or
not. And how/where one can find it in the standard whether the
implicit/explicit interface is valid or not.

Tobias

Richard Maine

unread,
Oct 6, 2009, 12:29:40 PM10/6/09
to
Tobias Burnus <bur...@net-b.de> wrote:

> On 10/05/2009 11:01 PM, James Van Buskirk wrote:
> > interface
> > function assumed_len(x)
> > character(5) assumed_len
> > integer, intent(in) :: x
> > end function assumed_len
> > end interface
>
> > function assumed_len(x)
> > character(*) assumed_len
> > integer, intent(in) :: x
> >
> > assumed_len = repeat(achar(64+modulo(x,32)),len(assumed_len))
> > end function assumed_len
>
>
> It is not clear to me whether this is valid or not. NAG f95 only allows
> it only with an implicit interface such as
> external assumed_len
> character(5) assumed_len
> and not an explicit interface as in the example.
>

> I found the following bits in the standard but I have problems to draw a
> solid conclusion from it.
>

...


> c) "If an explicit specific interface is specified by an interface body
> or a procedure declaration statement (12.3.2.3) for an external
> procedure, the characteristics shall be consistent with those specified
> in the procedure definition, except that the interface may specify a
> procedure that is not pure if the procedure is defined to be pure."
>
> Thus: assumed character length = characteristic and characteristic shall
> be "consistent" (whatever this means exactly).

I think that's what rules out the code that James showed. The special
rule for assumed length says that this characteristic has to be
diferent, but this requirement says that the characteristic has to be
"consistent." I do wish that were defined better, but from context hints
I'd interpret "consistent" to mean "the same" for yes/no characteristics
like assumed character length. If one tried to interpret "consistent"
differently here, I'd wonder why that same interpretation wouldn't apply
to the purity matter cited as an exception.

I suppose there is some ground for uncertainly here based on the
question of exactly how "consistent" is interpreted.

None of this stuff falls in the category of having required diagnostics,
so the fact of it being accepted by some compilers is not substantial
evidence of its standard conformance. Standard conformance is the only
question at issue as far as I'm concerned. The whole feature of assumed
character length is whacky. I would never recomend that anyone use it
(and even more so in such subtle ways).

Note that there are no such ambiguities for the simillar question about
assumed-length character functions as module procedures. Although you
can have such a module procedure, you can't directly reference it when
acessed via USE because you are not allowed to both access it via USE
and also redeclare things about it. I think someone once posted an
example of passing such a module procedure as an actual argument, with
the dummy argument declaration having the required different
characteristic. That's why I used the qualifier "directly"; that kind of
usage would also get no sympathy from me if someone tried it and ran
into problems. My lack of sympathy would also extend to lack of interest
in saying that a compiler vendor should wate any efort in trying to make
such a practice work if it didn't happen to.

James Van Buskirk

unread,
Oct 6, 2009, 9:20:36 PM10/6/09
to
"Richard Maine" <nos...@see.signature> wrote in message
news:1j75qow.1quicn2lt76t4N%nos...@see.signature...

> Note that there are no such ambiguities for the simillar question about
> assumed-length character functions as module procedures. Although you
> can have such a module procedure, you can't directly reference it when
> acessed via USE because you are not allowed to both access it via USE
> and also redeclare things about it. I think someone once posted an
> example of passing such a module procedure as an actual argument, with
> the dummy argument declaration having the required different
> characteristic. That's why I used the qualifier "directly"; that kind of
> usage would also get no sympathy from me if someone tried it and ran
> into problems. My lack of sympathy would also extend to lack of interest
> in saying that a compiler vendor should wate any efort in trying to make
> such a practice work if it didn't happen to.

It seems that you don't like assumed character length functions.
I don't blame you, as they aren't all that useful, but they came
about, as I see it, from the way character variables were implemented
in F77 and as a consequence didn't impose much of a cost on vendors
to implement.

But your (assumed) dislike of them seems to lead to incorrect
interpretations or recollections of what the standard says about
them. For example in N1601.pdf, C416:

"A type-param-value of * may be used only in the following ways:
...
(4) in an external function, to declare the character length
parameter of the function result."

And this seems to me to preclude assumed character length module
procedures.

Moving a little further along in section 4.4.1:

"A char-length type parameter value of * has the following
meaning:
...
(4) If used to specify the character length parameter of a function
result, any scoping unit invoking the function shall declare the
function name with a character length parameter value other than * or
access such a definition by host or use association. When the function
is invoked, the length of the result variable in the function is
assumed from the value of this type parameter."

So I don't see why that makes my interface block inconsistent with
those specified in the procedure definition because after all the
standard says the scoping unit invoking the function is supposed
to declare the function just in this manner.

Again in section 12.3.2.1.3, it says about functions to be invoked
as defined operations,

"The function result shall not have assumed character length."

Why does it say this here rather than just forbid them to be in
interface blocks entirely up in the preamble to section 12.3.2.1
unless writing an interface block for an assumed character length
function is allowed?

Richard Maine

unread,
Oct 6, 2009, 9:48:06 PM10/6/09
to
James Van Buskirk <not_...@comcast.net> wrote:

> (4) in an external function, to declare the character length
> parameter of the function result."
>
> And this seems to me to preclude assumed character length module
> procedures.

Indeed. Hmm. I was sure I recalled something along these lines of a
declaration that you could have only if the procedure was not actually
invoked (making it pointless). I thought I even recalled a Note in the
standard about it....

Ah. Found it. The Note appears to have been removed from f2003, but see
F95 Note 5.6. Apparently it was the interface body case I was recalling
rather than the module procdure case.

"An interface body may be specified for a dummy or external function
whose result has a character length parameter of * only if the function
is not invoked. This is because this characteristic has to be specified
to be the same in the interface body as in the procedure definition, but
in order to invoke such a procedure, the calling routine is required to
specify a length other than *."

> So I don't see why that makes my interface block inconsistent with

> those specified in the procedure definition...

Well, I agree that the wording isn't as clear as I'd like. And I do note
the switch from "consistent" to "same" in the above Note. But I'll take
the Note in the standard as better evidence than you (or me) not being
able to see why that makes it inconsistent. Although that is a Note, and
thus not normative, one of the purposes of Notes is to clarify
interpretation. The first sentence of that Note is seems pretty clear.

> Why does it say this here rather than just forbid them to be in
> interface blocks entirely up in the preamble to section 12.3.2.1
> unless writing an interface block for an assumed character length
> function is allowed?

Per the above Note, it is allowed to write an interface block; it is
just pointless, as you can't then invoke the procedure.

James Van Buskirk

unread,
Oct 6, 2009, 11:00:21 PM10/6/09
to
"Richard Maine" <nos...@see.signature> wrote in message
news:1j76gz4.ko25pq1at9rywN%nos...@see.signature...

It seems possible to me that the Note was removed in the next edition
because it was simply incorrect, not having been vetted to the same
standard as normative text in the first place. I claim wiggle room
on this issue while conceding wiggle room to you at the same time.
Of course, if the interface block specified an assumed character length
result variable and the function were passed as an actual argument
rather than invoked, I think we may be in agreement that it would
be standard.

Richard Maine

unread,
Oct 6, 2009, 11:10:57 PM10/6/09
to
James Van Buskirk <not_...@comcast.net> wrote:

> It seems possible to me that the Note was removed in the next edition
> because it was simply incorrect, not having been vetted to the same
> standard as normative text in the first place. I claim wiggle room
> on this issue while conceding wiggle room to you at the same time.

Granted.

Steve Lionel

unread,
Oct 8, 2009, 8:49:47 PM10/8/09
to
robin wrote:
> "Jared Ahern" <jared...@gmail.com> wrote in message
> news:71f1a01b-1d32-4b04...@33g2000vbe.googlegroups.com...
> | On Oct 5, 11:48 am, nos...@see.signature (Richard Maine) wrote:
> | > > - passing a(6) to dummy d(4) (should fail at compile time?)
> | >
> | > No. That's actually legal. It just passes the first 4 elements of
> | > the actual argument.
> |
> | Ah, I didn't realize that.
>
> Maine is wrong. It passes only the address of the first element of the array.

Well, no, Richard is correct, as usual. The Fortran standard doesn't
say anything about passing "the address". Don't confuse implementation
details with semantics. The semantics are as if only four elements are
passed. I will agree that the most likely implementation is to pass the
address of the first element, but that's not the only possible
implementation.

--
Steve Lionel
Developer Products Division
Intel Corporation
Nashua, NH

For email address, replace "invalid" with "com"

User communities for Intel Software Development Products
http://software.intel.com/en-us/forums/
Intel Software Development Products Support
http://software.intel.com/sites/support/
My Fortran blog
http://www.intel.com/software/drfortran

robin

unread,
Oct 11, 2009, 3:57:12 AM10/11/09
to
"Dan Nagle" <dann...@verizon.net> wrote in message news:haf38v$2dv$1...@news.eternal-september.org...

| Hello,
|
| On 2009-10-05 21:54:00 -0400, "robin" <rob...@bigpond.com> said:
|
| > "Richard Maine" <nos...@see.signature> wrote in message
| > news:1j73ud7.uiiuuf1eymtvkN%nos...@see.signature...
| > | Jared Ahern <jared...@gmail.com> wrote:
| > | [about array argument mismatches]
|
| > | > - passing a(6) to dummy d(4) (should fail at compile time?)
| > |
| > | No. That's actually legal. It just passes the first 4 elements of
| > | theactual argument.
| >
| > No, it passes the address of the first element.
|
| How any compiler actually implements argument association
| is unspecified. A given compiler need not use the same
| method in different circumstances.

Typically a descruiptor is used for arrays, which contains the
address.
As for the old style (F77 and earlier), pass array by address only
was the most common form, if not the only form, because the size
of the array was not passed. The called procedure picked up this address
and used it to access k elements (where k <= the dimensioned
actual argument array).

0 new messages