Google Groups unterstützt keine neuen Usenet-Beiträge oder ‑Abos mehr. Bisherige Inhalte sind weiterhin sichtbar.

errors/warnings for DO index variable redefinition

75 Aufrufe
Direkt zur ersten ungelesenen Nachricht

Thomas Koenig

ungelesen,
29.10.2012, 12:17:5429.10.12
an
We all know that code that modifies an index variable within a DO
statement to be non-conforming.

The question (as a quality of implementation issue) is when to
warn and when to issue an error.

Suppose we have the following code.

module foo
implicit none
contains

subroutine out(i)
integer, intent(out) :: i
end subroutine out

subroutine inout(i)
integer, intent(inout) :: i
end subroutine inout

subroutine unknown(i)
integer :: i
end subroutine unknown
end module foo

program main
use foo
implicit none
integer :: i
do i=1,10
call out(i)
call inout(i)
call unknown(i)
call no_explicit_interface(i)
end do
end program main

What should a good compiler do?

IMHO, it should

- issue an error for the call to out(), because i becomes undefined on
entry

- issue an unconditional warning for the call to inout(), because the
argument is not definable. Or maybe this should also be an error?

- issue a warning when asked to do so (e.g. with -Wall) for the
call to unknown. If the subroutine has an explicit interface,
the user should know what he or she intends with the dummy argument.

- issue a warning when asked to be really, really verbose for the
call to no_explicit_interface, because this is likely to break
a lot of legacy code.

Opinions?

Tobias Burnus

ungelesen,
29.10.2012, 12:45:2929.10.12
an
Thomas Koenig wrote:
> - issue an error for the call to out(), because i becomes undefined on
> entry

That's also what NAG's compiler does.


> - issue an unconditional warning for the call to inout(), because the
> argument is not definable. Or maybe this should also be an error?

Well, the code is valid - as long as "i" is not modified, e.g.

do i = 1, 5
call inout(i, .false.)
end do
call inout(i, .true.)

contains

subroutine inout(i, modify)
logical :: modify
if (modify) i = 100
end subroutine inout

Is a perfectly valid program. I don't think that one should warn by
default. Am not even sure whether it makes sense to warn with -Wall or
-Wextra.


> - issue a warning when asked to do so (e.g. with -Wall) for the
> call to unknown. If the subroutine has an explicit interface,
> the user should know what he or she intends with the dummy argument.

Hmm, I don't think that it makes much sense to have a warning here. But
of cause, one could add a warning "-Wmissing-intent". I am not sure
whether it is really needed. I do not see a particular application to DO
index variables.


> - issue a warning when asked to be really, really verbose for the
> call to no_explicit_interface, because this is likely to break
> a lot of legacy code.

I think you are looking for the option -Wimplicit-interface; otherwise,
I don't think a warning makes sense.


At the end, I think the only 100% working technique to detect such
issues it to run a run-time test like -fcheck=do.

Tobias

glen herrmannsfeldt

ungelesen,
29.10.2012, 15:49:0229.10.12
an
Thomas Koenig <tko...@netcologne.de> wrote:
> We all know that code that modifies an index variable within a DO
> statement to be non-conforming.

> The question (as a quality of implementation issue) is when to
> warn and when to issue an error.

> Suppose we have the following code.


(snip of subroutines whose dummy argument has the same
INTENT as its name)

> program main
> use foo
> implicit none
> integer :: i
> do i=1,10
> call out(i)
> call inout(i)
> call unknown(i)
> call no_explicit_interface(i)
> end do
> end program main

> What should a good compiler do?

> IMHO, it should

> - issue an error for the call to out(), because i becomes
> undefined on entry

I am not sure that the error is required by the standard, but
a good compiler should do it.

> - issue an unconditional warning for the call to inout(), because the
> argument is not definable. Or maybe this should also be an error?

Why is the argument not definable? inout means that the routine may
or may not change it, and may or may not use the value on entry.

It is the programmers responsibility to know which one.
Maybe a warning, but probably not by default.

> - issue a warning when asked to do so (e.g. with -Wall) for the
> call to unknown. If the subroutine has an explicit interface,
> the user should know what he or she intends with the dummy argument.

> - issue a warning when asked to be really, really verbose for the
> call to no_explicit_interface, because this is likely to break
> a lot of legacy code.

Otherwise, unknown and no_explicit_interface are pretty much the
same thing. In both cases, there is no INTENT.

Now, I do remember in one of my early Fortran programs,
in the Fortran 66 days, and when planning to work on a
calendar program. I wrote a subroutine that would print
large four digit numbers at the top of the page, given
one INTEGER argument. To do that, it has to separate out
the value of the four digits, and, in doing so, set the
argument to zero. (or some low value.) Maybe:

I4=N/1000
N=N-1000*I4
I3=N/100
N=N-100*I3
I2=N/10
N=N-10*I2
I1=N

(I think I knew about MOD, but somehow didn't use it.)

Now, that wouldn't have been so bad, but I wanted to test
out the subroutine:

DO 1 I=1234,6789,1111
1 CALL DATE(I)

forgetting that I would change.

Printing about 20 lines per page, and the system default
limit of 5000 lines, for a big stack of paper.

I think, though, that there are way too many subroutine calls
with DO variables, to have the warning on by default.

-- glen

Richard Maine

ungelesen,
29.10.2012, 16:30:3929.10.12
an
glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

> Thomas Koenig <tko...@netcologne.de> wrote:

> > - issue an unconditional warning for the call to inout(), because the
> > argument is not definable. Or maybe this should also be an error?
>
> Why is the argument not definable? inout means that the routine may
> or may not change it, and may or may not use the value on entry.

I think you may be misunderstanding either what "definable" means or
what the standard's requirements are. The standard requires that the
actual argument be definable if the dummy is intent(inout). That
requirement is completely independent of any question of whether the
dummy argument happens to get redefined; for inout, the standard
requires that the actual argument be definable regardless. Only for
unspecified intent do the requirements for the actual argument
definability depend in any way on whether the subroutine actual does
redefine the dummy.

I was going to say that the argument is not definable because the
standard says so. But on checking, I find, somewhat amusingly, that the
standard doesn't have a normative definition of "definable". There is a
definition in the glossary, but that definition is pretty vague, so I
looked for the normative one. It isn't there (at least in f2003).

If we go with the only thing there is, namely the one in the glossary,
it just says

"A variable is \tdef{definable}
if its value may be changed by the appearance of its designator on the
left of an assignment statement."

which I find a bit vague, and indeed almost circular. I *THINK* there is
an implication that definability as a property of a variable independent
of time or the particular place in the code. But it would be nice if
that were made explicit (and even nicer if it were nomative). IN
particular, I think this (non-normative) definition implies that if I is
a local variable that is definable outside of the loop, it is still
"definable" inside the loop because the definability of I doesn't
change. That's not to say that you are allowed to redefine I inside of
the loop (you aren't). Just that the term "definable" doesn't appear to
relate to whether you may redefine the value here, but instead that
there is anyplace where you could redefine it. I'll not stand behind
that deduction, but that's the way I think I read it.

So I conclude that the argument is "definable", even though you are not
allowed to redefine it in that particular place.

> I think, though, that there are way too many subroutine calls
> with DO variables, to have the warning on by default.

That's certainly so for subroutines with implicit interfaces. That
would, for example, include virtually all f77 code. Implicit interfaces
were the only possibility in 777, and I'd find it hard to imagine that
there were many f77 codes of significant size that didn't involve
passing DO variables as actual arguments somewhere or other.

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

Thomas Koenig

ungelesen,
29.10.2012, 16:36:4529.10.12
an
On 2012-10-29, glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

(DO loop index variable passed to intent(inout) dummy)

> Why is the argument not definable? inout means that the routine may
> or may not change it, and may or may not use the value on entry.

I understood the sentence (8.1.7.6.2 The execution cycle) in
08-007r2:2008/03/11 that way:

"Except for the incrementation of the DO variable that occurs in
step (3), the DO variable shall neither be redefined nor become
undefined while the DO construct is active."

where definable is defined as (2.1.36) as

"being capable of definition and permitted to become defined"

which I think means that INTENT(INOUT) is illegal, but maybe I am
missing some subtle English language point here.

glen herrmannsfeldt

ungelesen,
29.10.2012, 17:56:2329.10.12
an
Richard Maine <nos...@see.signature> wrote:
> glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

>> Thomas Koenig <tko...@netcologne.de> wrote:

>> > - issue an unconditional warning for the call to inout(), because the
>> > argument is not definable. Or maybe this should also be an error?

>> Why is the argument not definable? inout means that the routine may
>> or may not change it, and may or may not use the value on entry.

> I think you may be misunderstanding either what "definable" means or
> what the standard's requirements are. The standard requires that the
> actual argument be definable if the dummy is intent(inout).

One of those. For one, I thought he was writing about the dummy
argument.

> That
> requirement is completely independent of any question of whether the
> dummy argument happens to get redefined; for inout, the standard
> requires that the actual argument be definable regardless. Only for
> unspecified intent do the requirements for the actual argument
> definability depend in any way on whether the subroutine actual does
> redefine the dummy.

And note from the next post, it only mentions redefining and
undefining, but not ordinary defining. It might, for example,
be a copy-in/copy-out, which would not change the value, and
maybe not count as redefining.

> I was going to say that the argument is not definable because the
> standard says so. But on checking, I find, somewhat amusingly, that the
> standard doesn't have a normative definition of "definable". There is a
> definition in the glossary, but that definition is pretty vague, so I
> looked for the normative one. It isn't there (at least in f2003).

How about redefinable or undefinable?

> If we go with the only thing there is, namely the one in the glossary,
> it just says

> "A variable is \tdef{definable}
> if its value may be changed by the appearance of its designator on the
> left of an assignment statement."

(snip)

> So I conclude that the argument is "definable", even though you
> are not allowed to redefine it in that particular place.

Is it considered redefining, as opposed to defining, if you
assign it the same value? More specifically:

I=I

>> I think, though, that there are way too many subroutine calls
>> with DO variables, to have the warning on by default.

> That's certainly so for subroutines with implicit interfaces. That
> would, for example, include virtually all f77 code. Implicit interfaces
> were the only possibility in 777, and I'd find it hard to imagine that
> there were many f77 codes of significant size that didn't involve
> passing DO variables as actual arguments somewhere or other.

-- glen

Phillip Helbig---undress to reply

ungelesen,
29.10.2012, 18:12:1529.10.12
an
In article <1ksq9o7.lbusxlmy0o56N%nos...@see.signature>,
nos...@see.signature (Richard Maine) writes:

> I think you may be misunderstanding either what "definable" means or
> what the standard's requirements are. The standard requires that the

I am paging through this thread and, without seeing the headers, knew
after the first line above that this post was from Richard Maine.

What is the shortest Fortran program with the same functionality?

Steven G. Kargl

ungelesen,
29.10.2012, 18:25:3129.10.12
an
On Mon, 29 Oct 2012 22:12:15 +0000, Phillip Helbig---undress to reply
wrote:
I = 42
END

:-)

Dan Nagle

ungelesen,
29.10.2012, 19:31:1129.10.12
an
Hi,

On 2012-10-29 20:36:45 +0000, Thomas Koenig said:

> "Except for the incrementation of the DO variable that occurs in
> step (3), the DO variable shall neither be redefined nor become
> undefined while the DO construct is active."
>
> where definable is defined as (2.1.36) as
>
> "being capable of definition and permitted to become defined"
>
> which I think means that INTENT(INOUT) is illegal, but maybe I am
> missing some subtle English language point here.

Methinks you have the English meaning exactly correct.

--
Cheers!

Dan Nagle

Richard Maine

ungelesen,
29.10.2012, 20:06:0529.10.12
an
glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

> And note from the next post, it only mentions redefining and
> undefining, but not ordinary defining. It might, for example,
> be a copy-in/copy-out, which would not change the value, and
> maybe not count as redefining.

I don't have time at the moment to explain that stuff in detail. But it
doesn't matter. The actual argument associated with an intent(inout) is
required to be definable. Period. That has nothing to do with the
implementation or what might or might not happen in the subroutine. If
the dummy is intent(inout), then the actual must be definable. There are
no other conditions.

And there is no actual distinction between
definable/redefinable/undefinable. In fact, the latter terms are never
used. The only reason that redefined is used is the potential for people
to get confused by the English into thinking that it isn't a definition
if the variable was already defined. There are no cases where a variable
is definable that you can't also redfine or undefine it.

And no, it doesn't matter whether you redefine it with the same value or
not. That's still a (re)definition.

I wrote this quickly enough that it might not be clear. But I'm afraid
that's all I have time for anyway. The short version is that there is no
useful content down that path. If you think you are finding some,then
you are confusing yourself... which isn't hard to do on the subject, I
admit.

Thomas Koenig

ungelesen,
30.10.2012, 16:08:0230.10.12
an
OK, to sum up the discussion:

Everybody agreed that passing a DO variable to an INTENT(OUT) dummy
is a Bad Idea.

Regarding passing a DO variable to an INTENT(INOUT) dummy argument:

- There was some ambiguity in F 2003 if this was allowed, based on
the lack of definition for the word "defined"

- The ambiguity was removed in F 2008, so this is now explicitly
forbidden (but a compiler is not required to check for this)

I think this means that it would be OK to issue a hard error for this.

In the absence of an INTENT on the dummy argument, the consensus
was not to warn.

Richard Maine

ungelesen,
30.10.2012, 19:48:3430.10.12
an
Thomas Koenig <tko...@netcologne.de> wrote:

> - There was some ambiguity in F 2003 if this was allowed, based on
> the lack of definition for the word "defined"

The ambiguity that I commented about was the lack of a definition for
"definable". I know of no particular problem with the word "defined".
Some people might be confused about defined vs redefined or undefined,
but I don't think there was actualy a problem with them in the standard
- just with "definable".

I agree with your conclusions. Just picking about that particular term.

--
Richard Maine
email: last name at domain . net
domain: summer-triangle

Ron Shepard

ungelesen,
31.10.2012, 03:18:5431.10.12
an
In article <1kssehh.bqbhgn1t0k87iN%nos...@see.signature>,
nos...@see.signature (Richard Maine) wrote:

> Thomas Koenig <tko...@netcologne.de> wrote:
>
> > - There was some ambiguity in F 2003 if this was allowed, based on
> > the lack of definition for the word "defined"
>
> The ambiguity that I commented about was the lack of a definition for
> "definable". I know of no particular problem with the word "defined".
> Some people might be confused about defined vs redefined or undefined,
> but I don't think there was actualy a problem with them in the standard
> - just with "definable".
>
> I agree with your conclusions. Just picking about that particular term.

I'm still trying to understand all of these situations, so here is a
question. Is it correct that any use of a do index as an actual
argument can be replaced with the equivalent expression.

do I = 1, N
call sub( (I), ...other arguments...)
enddo

In other words, are there any situations (with the various INTENT
specifications) where the argument I would be legal but the
expression (I) illegal, or visa versa?

$.02 -Ron Shepard

Ian Harvey

ungelesen,
31.10.2012, 05:10:1031.10.12
an
If the dummy had the TARGET (legal, but behaviour might change), POINTER
or ALLOCATABLE attributes?

Dick Hendrickson

ungelesen,
31.10.2012, 14:07:2031.10.12
an
I think you're right. A DO index can only be passed to an INTENT(IN) or
not specified intent dummy; and that's that same for expressions.
Likewise, (I) can't be passed to an INTENT(OUT) or INTENT(INOUT) dummy
and that's the same rule for a DO index. At least, that's my reading.

Dick Hendrickson

\"Vladimír Fuka <"name.surnameat

ungelesen,
01.11.2012, 11:13:3101.11.12
an

>> $.02 -Ron Shepard
> I think you're right. A DO index can only be passed to an INTENT(IN) or
> not specified intent dummy; and that's that same for expressions.


Also to VALUE dummies.
0 neue Nachrichten