experchange > fortran

Ron Shepard (02-04-19, 08:14 PM)
On 2/4/19 9:20 AM, FortranFan wrote:
> On Sunday, February 3, 2019 at 1:50:32 PM UTC-5, Ron Shepard wrote:
> Can @Ron Shepard present a minimal working example (MWE) illustrating the issue of "The need for a conditional allocation is very common"? Otherwise the comment appears inaccurate with current conforming compilers and the code snippet shown above appears entirely unnecessary given the current standard.


Consider the semantics of array assignment in the two cases:

A = <expression>
A(:,:) = <expression>

In f90, they both meant the same thing. Namely, A must be allocated and
the bounds of A and the rhs must match (and hopefully you can get the
compiler to tell you about the mismatches). In f2003, they mean
something different, and sometimes neither is what the programmer wants.
Hence the need for the conditional allocation code above and the need to
add (:,:) to expressions in legacy code.

In addition to getting the right size during the allocation, it is also
necessary sometimes to have the correct lower and upper bounds; f2003
allocate on assignment is limited in that respect too. I think it should
be allowed to access the array metadata to change, for example, A(1:5)
to A(-2:2), while leaving the elements unchanged. This is perhaps a
separate issue from the array allocation itself, but whether this is
done with allocate() or with assignment, it is part of the semantics.

$.02 -Ron Shepard
steve kargl (02-04-19, 08:58 PM)
Ron Shepard wrote:

> On 2/4/19 9:20 AM, FortranFan wrote:
> Consider the semantics of array assignment in the two cases:
> A = <expression>
> A(:,:) = <expression>
> In f90, they both meant the same thing. Namely, A must be allocated and
> the bounds of A and the rhs must match (and hopefully you can get the
> compiler to tell you about the mismatches). In f2003, they mean
> something different, and sometimes neither is what the programmer wants.
> Hence the need for the conditional allocation code above and the need to
> add (:,:) to expressions in legacy code.


If your code was standard conforming F90 or F95, you do not need to
add the (:,:). "A = <expr>" and "A(:,:) = <expr> must meet the
requirements of

7.5.1.4 Intrinsic assignment conformance rules

For an intrinsic assignment statement, variable and expr shall conform in shape,
and if expr is an array, variable shall also be an array. The types of variable and
expr shall conform with the rules of Table 7.9.
FortranFan (02-04-19, 10:34 PM)
On Monday, February 4, 2019 at 1:14:45 PM UTC-5, Ron Shepard wrote:

[..]
> Hence the need for the conditional allocation code above and the need to
> add (:,:) to expressions in legacy code.
> ..


@Ron Shepard,

See response by @steve kargl.

Again, you should try to put together a complete reproducer example using *standard-conforming* code where you think there is "the need for the conditional allocation code above and the need to add (:,:) to expressions" and post it on this forum thread. It need only be a few lines of code but enough that readers can examine the instructions, make some sense out of it, andbe able to compile and execute the instructions.

Your stating of a snippet such as "A = <expression>" is useless without some clear illustrations of the kind of <expression> you have in mind relative to the variable on the left-hand side.
gah4 (02-04-19, 11:00 PM)
On Monday, February 4, 2019 at 7:59:46 AM UTC-8, spectrum wrote:

(snip)

> RE automatic allocation of LHS, I've used the word "dangerous",
> but I'm afraid this word may have been too strong (I have no
> intention to offend the current standard or
> the efforts around this syntax). What I mean is that the
> user needs to be more careful about the meaning of "=" than previously,
> because it has now dual meaning of copy and possible reallocation.


I don't know about dangerous, either.

Some things, such as REAL DO variables, were considered so dangerous
as to remove them from the standard. (Yes, I have said that before.)

In this case, it can complicate debugging, especially of programs
written by others. Before, I can grep for ALLOCATE to find where
all the ALLOCATE and DEALLOCATE statements are.

Also, again when debugging programs written by others, if I find
an allocation being changed, I don't know if it is intentional
or a bug. Of course programmers could put a comment on
each one: ! reallocate on assignment here! or
! not changing the size here! but that is enough more work that
it undoes much of the savings. (Does anyone here do that?)

Yes allocate on assignment is a nice feature, but most other
features you have to ask to use. Not this one.

Note that there is no standard way to bounds check arrays,
likely a more common need then automatic reallocation.
robin.vowels (02-04-19, 11:51 PM)
On Monday, February 4, 2019 at 5:50:32 AM UTC+11, Ron Shepard wrote:
[..]
> endif
> if ( qalloc ) allocate(x(n))
> This functionality could easily be added to the language


It already exists with allocate on assignment,
without adding more clutter to the language.
[..]
Ron Shepard (02-05-19, 04:11 AM)
On 2/4/19 3:00 PM, gah4 wrote:
> On Monday, February 4, 2019 at 7:59:46 AM UTC-8, spectrum wrote: [...]
> In this case, it can complicate debugging, especially of programs
> written by others. Before, I can grep for ALLOCATE to find where
> all the ALLOCATE and DEALLOCATE statements are.


Before f2003 (or at least before the previous allocatable TR),
allocatable arrays are always associated with an ALLOCATE() statement
and they were always associated also with a DEALLOCATE statement. After
f2003, allocatable arrays could be allocated upon assignment, and
deallocation is automatic and typically neglected, so both statements
are no longer closely associated with the actual memory usage.

> Also, again when debugging programs written by others, if I find
> an allocation being changed, I don't know if it is intentional
> or a bug. Of course programmers could put a comment on
> each one: ! reallocate on assignment here! or
> ! not changing the size here! but that is enough more work that
> it undoes much of the savings. (Does anyone here do that?)


Yes, I have comments like that scattered throughout my codes. The main
reason is because of the false positive warning messages by compilers
warning the programmer that possible reallocation of the array may
occur. I want other programmers to know that the allocation is
intentional, not incidental, so that warning can be ignored for that
statement.

> Yes allocate on assignment is a nice feature, but most other
> features you have to ask to use. Not this one.
> Note that there is no standard way to bounds check arrays,
> likely a more common need then automatic reallocation.


This is a quality of implementation issue. Most compilers do support
some kind of optional array bounds checking, both compile time and run time.

$.02 -Ron Shepard
gah4 (02-05-19, 04:51 AM)
On Monday, February 4, 2019 at 6:11:12 PM UTC-8, Ron Shepard wrote:

(snip, I wrote)

> > Also, again when debugging programs written by others, if I find
> > an allocation being changed, I don't know if it is intentional
> > or a bug. Of course programmers could put a comment on
> > each one: ! reallocate on assignment here! or
> > ! not changing the size here! but that is enough more work that
> > it undoes much of the savings. (Does anyone here do that?)


> Yes, I have comments like that scattered throughout my codes. The main
> reason is because of the false positive warning messages by compilers
> warning the programmer that possible reallocation of the array may
> occur. I want other programmers to know that the allocation is
> intentional, not incidental, so that warning can be ignored for that
> statement.


Nice to know.

As I said, too late now, but I would have liked to see one
request allocate on assignment. One way might have been with the
REALLOCATABLE attribute, which in your case could have turned off
the message.

It might also have been nice to request it on the assignment,
though I haven't thought about syntax for that one. Would have
been nicer than using comments.

But comments work, too.
Ron Shepard (02-05-19, 04:58 AM)
On 2/4/19 3:51 PM, robin.vowels wrote:
> On Monday, February 4, 2019 at 5:50:32 AM UTC+11, Ron Shepard wrote:
> It already exists with allocate on assignment,
> without adding more clutter to the language.


Allocate on assignment does not eliminate the need for allocate
statements. Otherwise, allocate() would be deprecated, obsolescent, or
deleted from the language. Sometimes you want to allocate and array and
use it thereafter, just exactly as f90 provided and is still allowed now.

The good thing about the way allocation works in the allocatable TR and
later in f2003 is that any f90 or f95 standard-conforming code is still
standard conforming after f2003. The requests to see a counter example
of that are impossible, and I assume the requesters do not understand
those details, or they would not have asked for such an example.

Instead, the debugging problem is the other way around. An illegal
situation suddenly becomes legal, so the compiler cannot possibly tell
you that a mistake has occurred. Here is a trivial example:

subroutine assign( A, B )
integer, intent(inout), allocatable :: A(:,:)
integer, intent(in) :: B(:,:)
A = B
return
end

In f90, this would result in an error if the bounds do not match or if A
is not allocated, and with the appropriate compiler options, you could
get a runtime error message and traceback telling you so. In f2003, this
is no longer an error. Instead, A is silently (re)allocated if
necessary. This is the loaded gun pointed at your foot that I was
talking about before. This can result in frustrating debugging because
the subsequent errors from this reallocation may be difficult to trace
back to their source. If you had a pointer to the original array, now
that pointer is dangling. You are screwed every which way.

The other problem with this code is that when it is called correctly
(according to f90), the f2003 compiler must check the allocation status
before assignment and insert the optional code to perform the
allocation. This does not produce code errors, but it isn't what the
programmer originally intended -- those tests are redundant, and the
associated code is redundant. So now the programmer must go back and
change the legacy code to

A(:,:) = B(:,:)

to get back closer to what was originally intended, safe code with no
reallocation, no danger of dangling pointers, and so on.

As I posted before, allocation on assignment is useful, and I do not
know of a simple syntax change to fix these issues. I expect if there
were such a change it would have been implemented that way in the first
place. I think now we are just stuck with it.

But the conditional allocation that goes along with all of this could be
added in various ways to the language. That would eliminate the need for
the above code for all data types, intrinsic and derived, and for all
array ranks, including scalars.

$.02 -Ron Shepard
gah4 (02-05-19, 05:01 AM)
On Monday, February 4, 2019 at 6:11:12 PM UTC-8, Ron Shepard wrote:

(snip, I wrote)

> > Yes allocate on assignment is a nice feature, but most other
> > features you have to ask to use. Not this one.


> > Note that there is no standard way to bounds check arrays,
> > likely a more common need then automatic reallocation.


> This is a quality of implementation issue. Most compilers do support
> some kind of optional array bounds checking, both compile time and run time.


It is. But maybe it is time for it to be part of the language.

A way to specify, array by array, or statement by statement, that one
did or didn't want bounds checked.

I suppose compilers could do this now, with directives that look
like comments, but it really seems like it could be done
with actual statements.

Reminds me of the INDEX instruction for VAX, that makes it easier
to check bounds. Except that it turned out that, as implemented in
hardware, it was slower than the old way. (Maybe not for all
implementations, but the idea stuck.)

The ability to not check bounds could be used when one was already
sure of the code, and didn't want the overhead. Or when one was using
some indexing trick that fooled checks.
FortranFan (02-05-19, 05:53 AM)
On Monday, February 4, 2019 at 9:58:48 PM UTC-5, Ron Shepard wrote:

> .. The requests to see a counter example
> of that are impossible, and I assume the requesters do not understand
> those details, or they would not have asked for such an example.


@Ron Shepard,

Or it could be the requesters (sic) are trying to ascertain the details, for their understanding based on a reading of the standard documents do not jive with the alarms you raise.

> Instead, the debugging problem is the other way around. An illegal
> situation suddenly becomes legal, so the compiler cannot possibly tell
> you that a mistake has occurred. Here is a trivial example:
> subroutine assign( A, B )
> integer, intent(inout), allocatable :: A(:,:) ...
> In f90, this would result in an error ..


Indeed it should result in an error. But only because the standards towardFortran 90 as well as Fortran 95 revisions did *not* allow the ALLOCATABLEattribute with dummy arguments. Section 5.1 on page 48 of J3/97-007R2 document toward Fortran 95:

Constraint: The ALLOCATABLE attribute may be used only when declaring an array that is not a dummy argument ..

The rest of your arguments are irrelevant.

Anyways, as stated earlier, code conforming to Fortran 90, 95 standard revisions would have had to ensure the shapes of 'expr' on the right-hand side conform to those of the variable on the left-hand side in an 'A = B' assignment. Under such circumstances, no issues should arise with Fortran 2003and later revisions. But when the shapes did not conform, it was up to the coder to handle the situation and if that was done in a conforming manner, the code would function just as well with later standards; allocate-upon-assignment will not be of concern.

Your approach then of employing array section syntax 'A(:) = B(:)' makes little sense.
Ron Shepard (02-05-19, 08:37 AM)
On 2/4/19 8:51 PM, gah4 wrote:
> On Monday, February 4, 2019 at 6:11:12 PM UTC-8, Ron Shepard wrote:
> As I said, too late now, but I would have liked to see one
> request allocate on assignment. One way might have been with the
> REALLOCATABLE attribute, which in your case could have turned off
> the message.
> It might also have been nice to request it on the assignment,
> though I haven't thought about syntax for that one. Would have
> been nicer than using comments.
> But comments work, too.


Yes, it would need to be statement by statement. The declaration would
have to apply to every usage of the array within the subprogram, so that
is too broad. One possibility might have been to define a new assignment
operator (e.g. := or something like that) for the cases where
(re)allocation is allowed. But what is done is done, it is too late to
back that out now.

$.02 -Ron Shepard
Ron Shepard (02-05-19, 08:46 AM)
On 2/4/19 9:53 PM, FortranFan wrote:
> On Monday, February 4, 2019 at 9:58:48 PM UTC-5, Ron Shepard wrote:
> @Ron Shepard,
> Or it could be the requesters (sic) are trying to ascertain the details, for their understanding based on a reading of the standard documents do not jive with the alarms you raise.
> ..
> Indeed it should result in an error. But only because the standards toward Fortran 90 as well as Fortran 95 revisions did *not* allow the ALLOCATABLE attribute with dummy arguments. Section 5.1 on page 48 of J3/97-007R2 document toward Fortran 95:


Yes, that came later with the allocatable TR. Thank you for reminding
me. So change my example to a module array or a local array, and
everything else I said is correct.

[...]
> Your approach then of employing array section syntax 'A(:) = B(:)' makes little sense.


That is how you force an error for bounds mismatches now. How else do
you do it?

$.02 -Ron Shepard
edmondo.giovannozzi (02-05-19, 12:57 PM)
Il giorno marted́ 5 febbraio 2019 04:53:42 UTC+1, FortranFan ha scritto:
> On Monday, February 4, 2019 at 9:58:48 PM UTC-5, Ron Shepard wrote:
> @Ron Shepard,
> Or it could be the requesters (sic) are trying to ascertain the details, for their understanding based on a reading of the standard documents do notjive with the alarms you raise.
> ..
> Indeed it should result in an error. But only because the standards toward Fortran 90 as well as Fortran 95 revisions did *not* allow the ALLOCATABLE attribute with dummy arguments. Section 5.1 on page 48 of J3/97-007R2 document toward Fortran 95:
> Constraint: The ALLOCATABLE attribute may be used only when declaring an array that is not a dummy argument ..
> The rest of your arguments are irrelevant.
> Anyways, as stated earlier, code conforming to Fortran 90, 95 standard revisions would have had to ensure the shapes of 'expr' on the right-hand side conform to those of the variable on the left-hand side in an 'A = B' assignment. Under such circumstances, no issues should arise with Fortran 2003 and later revisions. But when the shapes did not conform, it was up to the coder to handle the situation and if that was done in a conforming manner, the code would function just as well with later standards; allocate-upon-assignment will not be of concern.
> Your approach then of employing array section syntax 'A(:) = B(:)' makes little sense.


I agree with @FortranFan, I like the reallocation on assignment and I have used it a lot of time.

I also use the fact that local allocatable variables are always deallocatedwhen entering a procedure and that intent(out) allocatable variables are automatically deallocated.

That means that most of that time I don't need to deallocate them or check if they are allocated. I can safely assume they are unallocated and use reallocation on assignment if I can or allocate them directly if I cannot.
FortranFan (02-05-19, 05:10 PM)
On Tuesday, February 5, 2019 at 1:46:52 AM UTC-5, Ron Shepard wrote:

> On 2/4/19 9:53 PM, FortranFan wrote:
> ..
> Yes, that came later with the allocatable TR. Thank you for reminding
> me. So change my example to a module array or a local array, and
> everything else I said is correct.
> ..
> That is how you force an error for bounds mismatches now. How else do
> you do it?
> ..


@Ron Shepard,

Given the fact you are alleging problems in Fortran standard which then lead to your "need for the conditional allocation code .. and the need to add (:,:) to expressions in legacy code", why don't you also try to explain your need to "force an error for bounds mismatches" in array assignments?

Or why don't you present yourself with a simple proposition that perhaps these "needs" can be dispensed with in your code?

You state 2 situations now, "a module array or a local array":

* Take the latter first involving "a local array": what code or method or algorithm do you have where "a local array" is anything but a *disposable object* such that in your "A = <expression>" assignment (where assuming A is your "local array") or any other array operations for that matter that you would really need to "force an error for bounds mismatches". Meaning whydo you think you cannot simply rely on current standard Fortran in terms of what it states a conforming processor will do with such operations (e.g.,intrinsic assignment) with "a local array" with the ALLOCATABLE attribute?My hunch is you do *not* really have such a need to "force an error for bounds mismatches", you may think you do but you might be mistaken.

* Now take your second case with "a module array" which then refers to an object with the SAVE attribute and thus the "state management" that necessarily follows such objects. It is entirely the responsibility of the coder of the module to do such "state management". And when such "state management" is carried out in a standard-conforming manner, then you should ask yourself why does your "A = <expression>" assignment (so here A is "a module array") need to "force an error for bounds mismatches"? The "state management" scheme in the module is the one to take care of bounds matches. So again my hunch is you do *not* really have such a need "force an error for bounds mismatches" with assignments involving "a module array" either, you may think you do but you might be mistaken.
Ron Shepard (02-05-19, 06:04 PM)
On 2/5/19 9:10 AM, FortranFan wrote:
> On Tuesday, February 5, 2019 at 1:46:52 AM UTC-5, Ron Shepard wrote: [...]
> * Take the latter first involving "a local array": what code or method or algorithm do you have where "a local array" is anything but a *disposable object* such that in your "A = <expression>" assignment (where assuming A is your "local array") or any other array operations for that matter that you would really need to "force an error for bounds mismatches".


Regardless of whether the array is a disposable object or a saved
object, it is still useful to generate array bounds mismatch errors when
they erroneously occur. A=<expression> would do that with f90 semantics,
but not with f2003.

Are you being purposely obtuse about that difference?

As for your other point, yes you can place the appropriate debug code
into the program to test for SIZE() along all of the dimensions of all
the arrays and do this testing manually. That has never been the issue.

$.02 -Ron Shepard

Similar Threads