From: Gib Bogle on
My question is motivated by concern about performance. I assume that
when I pass a variable that is a derived type as an argument to a
subroutine, is it passed by reference, just as fundamental types are.
Am I correct? For example (in a module):

type mytype
integer :: x,y,z
real :: w(1000)
end type

type(mytype) :: a
a%x = 1
a%y = 2
a%z = 3
call init(a)
....

subroutine initw(a)
type(mytype), intent(inout) :: a
a%w = 99
end subroutine
From: Richard Maine on
Gib Bogle <g.bogle(a)auckland.no.spam.ac.nz> wrote:

> My question is motivated by concern about performance. I assume that
> when I pass a variable that is a derived type as an argument to a
> subroutine, is it passed by reference, just as fundamental types are.

1. The standard does not specify that *ANYTHING* is passed by reference.
In practice, they often, but not always are. It is just plain incorrect
to say that "fundamental types are passed by reference". While they
sometimes are, they sometimes aren't. There are even some cases where
they pretty much cannot be.

2. However, that being said, it is just as likely that a derived type
object will be passed by reference. For the most part, the issues simply
don't have much to do with type. It is things orthogonal to type that
are much more important to the question of how arguments are passed. If
anything, to the extent that type matters, I would say that it is the
fundamental types that have greater odds of being passed by something
other than reference.

3. But as you say that your question is motivated by performance issues,
I'd say that you have expressed it in terms that don't really capture
that. Presumably, you don't really care so much about whether it is
passed by reference as whether it has performance comparable to that
expected of pass-by-reference. The answer to that is basically yes.

4. But to reiterate a point made above - a really, really important
point worthy of reiteration - type is *NOT* the most important factor
here. You can get copy-in/copy-out argument passing that can (in some
cases) cause really horrid performance. But the things that typically
trigger that have nothing to do with type. They have much more to do
with array issues and apply to all types.

--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain
From: Gib Bogle on
Richard Maine wrote:
> Gib Bogle <g.bogle(a)auckland.no.spam.ac.nz> wrote:
>
>> My question is motivated by concern about performance. I assume that
>> when I pass a variable that is a derived type as an argument to a
>> subroutine, is it passed by reference, just as fundamental types are.
>
> 1. The standard does not specify that *ANYTHING* is passed by reference.
> In practice, they often, but not always are. It is just plain incorrect
> to say that "fundamental types are passed by reference". While they
> sometimes are, they sometimes aren't. There are even some cases where
> they pretty much cannot be.
>
> 2. However, that being said, it is just as likely that a derived type
> object will be passed by reference. For the most part, the issues simply
> don't have much to do with type. It is things orthogonal to type that
> are much more important to the question of how arguments are passed. If
> anything, to the extent that type matters, I would say that it is the
> fundamental types that have greater odds of being passed by something
> other than reference.
>
> 3. But as you say that your question is motivated by performance issues,
> I'd say that you have expressed it in terms that don't really capture
> that. Presumably, you don't really care so much about whether it is
> passed by reference as whether it has performance comparable to that
> expected of pass-by-reference. The answer to that is basically yes.
>
> 4. But to reiterate a point made above - a really, really important
> point worthy of reiteration - type is *NOT* the most important factor
> here. You can get copy-in/copy-out argument passing that can (in some
> cases) cause really horrid performance. But the things that typically
> trigger that have nothing to do with type. They have much more to do
> with array issues and apply to all types.
>

Thanks. Some code timing with a range of sizes of my derived type
convinced me that there is no significant performance penalty for large
types on my system, and as you point out that's all I'm really concerned
about.
From: Arno on
> 1. The standard does not specify that *ANYTHING* is passed by reference.
> In practice, they often, but not always are.

I also thought that in Fortran the default was passing arguments by
reference and that passing by value has to be explicitely stated. I
also thought that an argument changed in a subroutine is changed in
the caller as well. I make pretty often use of that, so I really hope
I can rely on the fact that arguments are passed by reference.

See for instance below:

program test

integer :: i
i = 2

call mycalc(i)

write(*,*) i

end program

subroutine mycalc(val)

integer :: val

val = val*2

end subroutine

Would the printed value always be 4, or is it undefined as the passing
of arguments can be either by reference or value, dependent on
compiler, platform etc.!?

Arno
From: Dan Nagle on
Hello,

You are very badly confusing mechanism
with effect.

Argument association, as it's called, is
a set of rules regarding the relationship
between actual arguments and dummy arguments.
Said rules are specified.

The mechanism by which those the relationship
is made to occur is not specified.

An applications programmer is entitled
to use the specified rules as needed.
The compiler is entitled to create
the illusion as it prefers.

Endit. :-)

On 2008-04-17 08:12:49 -0400, Arno <arnoinperu(a)hotmail.com> said:

>> 1. The standard does not specify that *ANYTHING* is passed by reference.
>> In practice, they often, but not always are.
>
> I also thought that in Fortran the default was passing arguments by
> reference and that passing by value has to be explicitely stated. I
> also thought that an argument changed in a subroutine is changed in
> the caller as well. I make pretty often use of that, so I really hope
> I can rely on the fact that arguments are passed by reference.
>
> See for instance below:
>
> program test
>
> integer :: i
> i = 2
>
> call mycalc(i)
>
> write(*,*) i
>
> end program
>
> subroutine mycalc(val)
>
> integer :: val
>
> val = val*2
>
> end subroutine
>
> Would the printed value always be 4, or is it undefined as the passing
> of arguments can be either by reference or value, dependent on
> compiler, platform etc.!?
>
> Arno


--
Cheers!

Dan Nagle