From: dpb on
ivan martin wrote:
....

> ... I was wondering why when we do the above,
> in the main program need to state that something is a parameter
>
> INTEGER, PARAMETER : N
>
> but in the subroutine we just state
>
> INTEGER, INTENT(IN) :: N
>
> (e.g. we don't say that N is a parameter).
>
> Parameter == named constant ? Maybe ? But why does then work in the main program
> just to write
>
> INTEGER :: N=100
>
> (e.g. this is also a named constant).

No, the latter is _NOT_ a named constant; it's an integer variable. The
difference is that after

INTEGER, PARAMETER :: N = 100

in a program unit an assignment statement or other attempt to modify N

such as

N = 200

will result in a compiler error letting you know you screwed up in
trying to modify a value that was intended as a constant.

OTOH,

INTEGER :: N=100

is a declaration of an (default length) integer variable with an
initialization expression setting its starting value. But, you could
follow this by another assignment statement

N = 200

and it would from that point in program execution (until changed again,
perhaps) have the new value of 200.

Two completely different things, parameters and variables.

--
From: glen herrmannsfeldt on
ivan martin <i.martin(a)invalid.com> wrote:
> On Wed, 19 May 2010 12:44:42 -0500, mecej4 <mecej4_no_spam(a)operamail.com> wrote:
>>On 5/19/2010 12:26 PM, ivan martin wrote:
>>> Maybe a naive question, but why do we need when in main program
>>> !************
>>> integer, parameter :: n=100
>>> real, dimension(n) :: my_array

>>> but when in a subroutine

>>> subroutine my_subroutine(n,array)
>>> integer, intent(in) :: n
>>> real, dimension(n), intent(inout) :: array

>>> e.g. where did the "parameter" go ?
>>> (I'm sure you understand what I'm aiming on by now)

>>> Shouldn't parameter keyword be used every time we wish to,
>>> for example, declare an array ?

>>That is a valid, if naive, question.

>>The use of a parameter (named constant) is not required, but using one
>>makes the code more readable and easier to modify. If I have 15 arrays
>>of size 100, and I want one day to enlarge them to size 200, with the
>>declared parameter I change one instance of 100 to 200, instead of 15
>>instances of 100.

> You misunderstood though - I probably could've putted the question
> better also. I wasn't asking why about declaring size of arrays
> with parameters, instead of explcitly writing them out in
> declarations, but something else. I was wondering why when we do
> the above, in the main program need to state that something is
> a parameter

They are very different, and the difference goes back at least
to Fortran 66. In both cases the size has to be known before
entering the routine. For MAIN, that means known at compile time.
Space is actually allocated for the array, potentially in static
allocation memory.

In the subroutine, no space is allocated for the array, at least
not in most cases. For the give problem, it would work just as
well if the one in the subroutine said:

real, dimension(*), intent(inout) :: array

(well, not in Fortran 66, but (1) was often used.)

Fortran 66 and 77 allow for implementation with only static allocation.
Since the subroutine is using the allocated space from the calling
routine, it isn't allocating anything for the array, and so it is
allowed for the dimension to be a variable. That variable much have
a value before the subroutine is called.

Note that newer versions of Fortran allow for automatic arrays
using the size passed as an argument. It might even be possible
that automatic arrays in MAIN could be allocated based on command
line parameters, or environment variables.

In any case, the size of a static array needs to be known at
compile time, and the size of an automatic array needs to be
known at block entry.

-- glen
From: Craig Powers on
ivan martin wrote:
> Maybe a naive question, but why do we need when in main program
> !************
> integer, parameter :: n=100
> real, dimension(n) :: my_array
>
> end
> !************

Here, n is an integer with the parameter attribute, which may be used as
an actual argument for any external or module routine which doesn't try
to modify the associated dummy.

> but when in a subroutine
>
> !************
> subroutine my_subroutine(n,array)
> integer, intent(in) :: n
> real, dimension(n), intent(inout) :: array
> <snip some code>
>
> end subroutine my_subroutine
> !************

Here, n is a dummy argument which just happens to have the same name as
the n in the main program, but which isn't the same thing. Because this
n is intent(in), the compiler will not allow it to be modified, so it is
legal to use the n in the main program as the actual argument
corresponding to this dummy argument when my_subroutine is called.

> e.g. where did the "parameter" go ?

Uh, nowhere. n is still a parameter in the main program.

> Shouldn't parameter keyword be used every time we wish to,
> for example, declare an array ?

Not at all.
From: Craig Powers on
Craig Powers wrote:
> ivan martin wrote:
>> Maybe a naive question, but why do we need when in main program
>> !************
>> integer, parameter :: n=100
>> real, dimension(n) :: my_array
>>
>> end
>> !************
>
> Here, n is an integer with the parameter attribute, which may be used as
> an actual argument for any external or module routine which doesn't try
> to modify the associated dummy.
>
>> but when in a subroutine
>>
>> !************
>> subroutine my_subroutine(n,array)
>> integer, intent(in) :: n
>> real, dimension(n), intent(inout) :: array
>> <snip some code>
>>
>> end subroutine my_subroutine
>> !************
>
> Here, n is a dummy argument which just happens to have the same name as
> the n in the main program, but which isn't the same thing. Because this
> n is intent(in), the compiler will not allow it to be modified, so it is
> legal to use the n in the main program as the actual argument
> corresponding to this dummy argument when my_subroutine is called.
>
>> e.g. where did the "parameter" go ?
>
> Uh, nowhere. n is still a parameter in the main program.
>
>> Shouldn't parameter keyword be used every time we wish to,
>> for example, declare an array ?
>
> Not at all.

To expand on this, it occurs to me that you may also be confused by
array and my_array. my_array is a real with rank 1 and size n (main
program n), fixed at compile time, cannot be resized. array is an array
dummy argument with rank 1 and AT LEAST n elements; something called
sequence association applies any time my_subroutine is called, and
regardless of what the actual array is that is associated with the dummy
named "array", the first n (my_subroutine n) elements of the actual
array will be accessed through that dummy in my_subroutine.

Which is to say, things are different for a dummy argument vs. a
variable, which seems to be the root of most of your concerns.
From: Richard Maine on
Craig Powers <craig.powers(a)invalid.invalid> wrote:

> ivan martin wrote:

> > Shouldn't parameter keyword be used every time we wish to,
> > for example, declare an array ?
>
> Not at all.

In particular, although you *CAN* use parameters for such purposes, you
don't generaly want to. You could make a parameter n in your subroutine
if you wanted instead of passing it as an argument. Do note the "instead
of". It can't be both a parameter and a dummy argument; one or the
other. They are very different. A parameter is a named constant. A dummy
argument is a variable and gets the value of whatever is passed to it.

If you use a parameter for the array size in the subroutine, then that
array size is fixed for the entire program. In order to change it, you
have to change the value of the parameter and recompile.

For some subroutines, that is fine. But other subroutines need to be
able to handle arrays of different sizes. Think about a trivial case
such as a subroutine to add two arrays. (One wouldn't normally write
that particular subroutine because the language does it for you, but is
a simple example). If you wrote it with parameters for the array
dimensions, you would only be able to add one particular size of array
in any run of the program. To be able to add two different sizes of
array, you would need two different subroutines. That would be...
awkward... to say the least.

If you use a dummy argument instead of a parameter, then you can have
one subroutine to handle any size of array.

Or, in Fortran 90 or later (and I see that the code uses other f90
features anyway), one might consider using assumed-shape dummy arrays.
Then the array size information is passed for you. That makes for
simpler argument lists and helps avoid a large class of common
programming errors related to having the dummy argument declaration
inconsistent with the actual argument.

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