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

Nested Declarations

21 views
Skip to first unread message

PGK

unread,
Sep 10, 2009, 10:54:25 AM9/10/09
to
Hi, I'm wondering, are there any Fortran statements which allow nested
variable declarations. For example in many C/C++ constructs, such as a
for-loop or basic block, variables can be declared; even with the same
name as existing ones. Is there anything like this:

integer :: a
...
foo_statement
integer :: a, b
...
end foo_statement


Many thanks,
Graham

dpb

unread,
Sep 10, 2009, 12:21:26 PM9/10/09
to
...

No; Fortran scopes on program units (program, subroutine, function) and
declaration and parameter statements must precede executable statements.

--

Richard Maine

unread,
Sep 10, 2009, 12:36:52 PM9/10/09
to
PGK <graha...@gmail.com> wrote:

Yes, there are some cases of that, but I think you are asking about
something more general. Off the top of my head, derived-type
declarations and interface bodies occur to me as constructs that
establish a new scope and allow declarations in the new scope, so yes
there are statements which do that. But those is nothing that does
*ONLY* that and thus can be used in the manner that I think you are
asking about.

Such things have at least been discussed before, but I don't recall the
details of the discussions. It occurs to me that scope is a central
enough concept that introducing such a thing might well end up a more
complicated project than is at first evident. That might have been a
reason for rejection, but I'm speculating as I don't actually recall
that level of detail.

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

Daniel Kraft

unread,
Sep 10, 2009, 12:38:16 PM9/10/09
to

I'm no expert on these stuff, but IIRC the upcoming Fortran standard
(Fortran 2008), which is currently in development, will include a BLOCK
construct that does exactly what you want.

It would then be:

integer :: a
...
block
integer :: a, b
...
end block

Yours,
Daniel

--
Done: Arc-Bar-Cav-Ran-Rog-Sam-Tou-Val-Wiz
To go: Hea-Kni-Mon-Pri

Dick Hendrickson

unread,
Sep 10, 2009, 12:38:57 PM9/10/09
to
Not really, at least not yet. Fortran 2008 has a BLOCK construct that
is mostly designed to allow nested declarations with local scope. You
can sort of fake it in F90 with internal procedures; but that's really
perverse and unreadable.

Dick Hendrickson

Tim Prince

unread,
Sep 10, 2009, 12:59:07 PM9/10/09
to
And you want the ability to generate broken code such as we often see in
C++ applications, where the programmer makes a different choice from the
standard about the point where the inner declaration goes out of scope?

Richard Maine

unread,
Sep 10, 2009, 2:58:33 PM9/10/09
to
Tim Prince <tpr...@nospamcomputer.org> wrote:

> PGK wrote:
[asks for what is probably the f2008 block construct]


> And you want the ability to generate broken code such as we often see in
> C++ applications, where the programmer makes a different choice from the
> standard about the point where the inner declaration goes out of scope?

Ah yes. I don't know C++, but recollections of some Fortran issues are
begining to come back. Multiple places in the Fortran standard
specifically list things that can make something go out of scope. I'm
thinking in particular of places that talk about events that can happen
as a result of a return or end statement. As per my usual, I would
rather these have talked a little more abstractly instead of about the
particular bits of syntax that can currently make it happen.

I wonder whether they all got found and fixed in introducing BLOCK to
f2008. Ah heck. I'll go grab a current copy of the draft and take a look
while I'm still waking up. Hmm... Maybe I'm not yet awake enough, but it
doesn't look good. Looks like exactly the kind of thing where something
got put in without thinking about all the ways it interacted with the
rest of the standard. Granted, I'm skimming, so I could have missed
major stuff. I have the CD dated 25 March 2009. That's what I found on
the J3 site. Let's see...

First, a sanity check on something that would change lots of things.
Such a block is not a scoping unit (1.3.113).

The section on the block construct itself (8.1.4) says that the
specifications in it declare construct entities, whose scope is the
construct. THat's pretty much all it says, though.

Hmm. That makes me wonder about implicitly declared things that don't
have specifications. Ok, the old words in 5.5, para 4 (I like the new
paragraph numbering - makes citation easier) seem to cover that ok.
Looks like implicit declarations always declare things to have the scope
of a scoping unit - never a construct. Not sure whether that was thought
about or just happened that way. Guess I don't see a problem; at least
it is clearly (to me) specified.

On to clause 16, where I expected much of the meat. 16.4 is the
subclause about statement and construct entities. Oh dear! It says
almost nothing useful here. It verifies that things declared in a block
construct are construct entities, and there is all the general material
about how construct entities override host associated or global ones.
But I don't see *ANY* material on all the interesting questions. The
other kinds of construct entities were all so limited that most of the
questions didn't come up. We still have the simple rule that two
construct entities cannot have the same identifier. How about some of
the rules in 16.3.1; those are different in block constructs? For
example, you can't have a derived type the same name as a procedure or
any of the other exceptions to the simple rule? Admitedly some of those
exceptions are a bit messy, but it seems even messier to allow them some
places but not others. Construct entities are specifically excluded from
the list of local identifiers discussed in 16.3.1.

Heck, I'd look for just about any appearance of the term "scoping unit"
as having potential problems. Alas, there are a lot of appearances of
that term. That's because the block construct introduces something that
is a lot like a scoping unit, but isn't one. Maybe it really should be
one. That might solve a lot of those problems. But then it might
introduce others.

Hmm. You don't have host association into blocks. I suppose that's
because they are not scoping units and so don't need it. But I sure
wonder how it manages to get by without at least some of the material
related to host association. Oh, for a messy example, can you declare a
generic in a block? I can't think of why not... except that the
complicated rules for generic resolution are all tied into host
association and scoping units (12.5.5).

There at least does appear to be some attention given to talking about
when construct variables become undefined (16.6.6(22)). I note a
difference between (22) and (3) in the same list, though,...

Which brings me back to something else I skipped over before - COMMON
blocks. I can't figure out what would be going on with those. None of
the material about common blocks appears to have anything about teh
block construct added. looks like common blocks are still all described
in terms of scoping units that reference them (including the bit in
16.6.3(3) about undefinition when going out of scope). I see multiple
contradictions here. Does a common statement in a block extend a common
statement for the same common name outside of the block? That doesn't
make much sense. Does it declare a separate instance of the common
block? That would seem more consistent with many things, except for all
the places where common blocks are tied to scoping units.

Can there be automatic objects in a block? I'm looking at 16.6.5(21) and
noting that it seems to assume that an automatic object must belong to a
procedure.

Well, that's (quite a lot more than) enough on this. I have to go do
some real work. This was all from just a fast skim through the CD. I
could possibly have missed a few things that fix it all. But I'm
guessing that the opposite is true - that when the BLOCK construct was
added people skimmed for places that they thought needed corresponding
modification, but they missed the hard fundamental ones. I think the
result is pretty much unrescuable.

I think the most fundamental question is whether a block is or is not a
scoping unit. Either answer makes for a mess, though the resulting
messes are different. There is just to much material that refers to
scoping units.

I'm betting that this kind of problem was why block constructs got
rejected in prior standards. Apparently it got reproposed and accepted
without the same degree of scrutiny as before. I'm surprised Malcolm
didn't catch this. Of course, maybe he did and got outvoted.

Reinhold Bader

unread,
Sep 10, 2009, 6:09:28 PM9/10/09
to
Hello,

Richard Maine schrieb:
> Tim Prince <tpr...@nospamcomputer.org> wrote:
>
[...]

I certainly don't know very many details about the BLOCK construct, but
in the last few meetings quite a number of amendments were done, so it
might be better to consult the FCD N1791 (on the WG5 web server). I'm
referencing that document in the following.

>
> Which brings me back to something else I skipped over before - COMMON
> blocks. I can't figure out what would be going on with those.

This appears to be dealt with by additional constraints C806 C807 in
8.1.4. (I am wondering a bit that dummy procedure arguments are not
flat-out included in this list, instead of INTENT). It probably also would
be a good idea to exclude some other items, like ENTRY.

>None of
> the material about common blocks appears to have anything about teh
> block construct added. looks like common blocks are still all described
> in terms of scoping units that reference them (including the bit in
> 16.6.3(3) about undefinition when going out of scope). I see multiple
> contradictions here. Does a common statement in a block extend a common
> statement for the same common name outside of the block? That doesn't
> make much sense. Does it declare a separate instance of the common
> block? That would seem more consistent with many things, except for all
> the places where common blocks are tied to scoping units.
>
> Can there be automatic objects in a block? I'm looking at 16.6.5(21) and
> noting that it seems to assume that an automatic object must belong to a
> procedure.

5.2.2 para 2 does mention this issue, although 16.6.5(21) appears to remain
spurious.

Regards
Reinhold

Jim Xia

unread,
Sep 10, 2009, 8:38:22 PM9/10/09
to
The entities declared within BLOCK constructs are categorized as
"construct entities". Their properties are described in 16.4. These
are in the same category as i in (/(i, i=1,100)/). And their scopes
are refined within the BLOCK construct. For those don't have explicit
declaration, it is "as if" declared outside the construct. So in that
case the entities leaked out of the construct.

During the August J3 meeting, one issue uncovered is the ASYNCHRONOUS
attribute to entities within the construct. If they're implicitly
typed, then its scope is beyond the BLOCK construct, and there are no
rules/constraints saying the attribute can be confined within the
block. So it makes sense to disallow ASYNCHRONOUS or VOLATILE
altogether for them. This is likely to be one of the comments on the
FCD.

Cheers,

Jim

Richard Maine

unread,
Sep 10, 2009, 9:10:51 PM9/10/09
to
Jim Xia <jim...@hotmail.com> wrote:

> The entities declared within BLOCK constructs are categorized as
> "construct entities". Their properties are described in 16.4.

Yes, so I saw in my quick skim. But that just doesn't say a fraction of
the things that need to be said about them. Did you miss all my
questions? Or do you really think that 16.4 answers them?

> These are in the same category as i in (/(i, i=1,100)/)

Yes, but things like that i are so limited that most of the questions
don't come up, which is probably why 16.4 doesn't address them. The
entities declared in a BLOCK construct raise many, many issues that just
don't come up for the other statement and construct entities.

I mentioned some of them in my prior post. Ok, my post was done pretty
stream-of-consciousness and is a bit "randomly" organized. Just to pick
a single (and very messy) example, can you explain how generic
declarations and resolution work in blocks? (And can you back such
explanation with citations from the draft standard? I won't even
restrict you to 16.4) That whole question just doesn't come up for the
other construct entities.

There are rules about how to combine generic procedures declared in a
host, accessed via USE, and declared locally. But those rules are all in
terms of scoping units. Since a block is not a scoping unit, they don't
apply.

Any generic declarations in the block are in the same scoping unit as
ones outside of the block, so by a literal reading of the generic rules,
they should have the same effect as though they were outside of the
block. But that seems both odd and also directly contradicted by the
statement that specifications inside of the block declare construct
entities.

The closest I can come is the fallback of "the standard does not
establish an interpretation (or perhaps establishes contradictory
interpretations) so it must be illegal".

If you can find discussion of this question in 10.4, either your eyes
are a lot better than mine, or it has been added after the 25 Mar 2009
draft that I was looking at.

And that is basically just one question among a whole host. Admitedly it
is a particularly nasty one.

I find myself drawn back to Dick Hendrickson's comment that

>> You can sort of fake it in F90 with internal procedures; but that's
>> really perverse and unreadable.

Perverse though it might be, I'm finding myself thinking that approach
is a lot better worked out in the standard than this new BLOCK construct
that looks to be severely shortchanged in terms of integration with the
rest of the standard. An internal procedure is a separate scoping unit
and all the rules deal appropriately with it. The only thing I can see
that makes it unreadable is that the body has to be moved down to after
the CONTAINS statement. That's a little disconcerting, but "unreadable"
seems an overstatement. Perverse I'd agree with. I'm assuming we are
talking the same kind of thing, where the internal procedure is just a
subroutine with no arguments, so the OP's example turns into

...
integer :: a
....
call foo
....
CONTAINS
subroutine foo
integer :: a, b
...
end subroutine foo

Now I happen to think it a really, really bad idea to have two different
"a" variables like that running around close enough to be easily
confused. If that's what Dick means by unreadable, I guess I'd agree.
But that's what the OP was asking for - not just a consequence of using
an internal procedure to do it.

Jim Xia

unread,
Sep 10, 2009, 10:00:28 PM9/10/09
to

> I mentioned some of them in my prior post. Ok, my post was done pretty
> stream-of-consciousness and is a bit "randomly" organized.

I wish I had more time to discuss more language issues in this forum :-
( No, I didn't read your earlier notes.


Just to pick
> a single (and very messy) example, can you explain how generic
> declarations and resolution work in blocks? (And can you back such
> explanation with citations from the draft standard? I won't even
> restrict you to 16.4) That whole question just doesn't come up for the
> other construct entities.
>
> There are rules about how to combine generic procedures declared in a
> host, accessed via USE, and declared locally. But those rules are all in
> terms of scoping units. Since a block is not a scoping unit, they don't
> apply.
>

Block constructs live within scoping units. I don't unserstand the
statement why the rules do not apply. Citation of 2nd paragrph of 16.4

"If a global or local identifier is the same as that of a construct
entity, the identifier is interpreted within the
construct as that of the construct entity. Elsewhere in the scoping
unit, the identifier is interpreted as the global
or local identifier."

So if you wish to declare a new generic name within the BLOCK (I hope
I understood your question), then that name MUST refers to the
construct entity within the construct. Outside the construct, follow
the rules for scoping units. Maybe I'm not getting your question
clear.


Cheers,

Jim

Richard Maine

unread,
Sep 10, 2009, 10:23:45 PM9/10/09
to
Jim Xia <jim...@hotmail.com> wrote:

> So if you wish to declare a new generic name within the BLOCK (I hope
> I understood your question), then that name MUST refers to the
> construct entity within the construct. Outside the construct, follow
> the rules for scoping units. Maybe I'm not getting your question
> clear.

No, I'd say you weren't understanding the issues involved at all. Not
worth detailing them here, as it is all quite complicated. Go look at
all the rules for declaring generics and for resolving them. I can't
even remember all of them and I don't see much point in trying to
explain them here. Instead, I can only suggest that you go read the
details in the standard. Since I can't even remember the details of the
rules, I'm betting that you can't either. But even though I don't recall
all the details, I do recall enough to see the conflicts here.

Generics are different from other names - very different. You can build
up a generic with pieces from multiple scoping units. You can inherit
part of it from a host, import part via USE, and declare part locally.
Locally declared generics do *NOT* override ones from a host - at least
not anywhere else in the language. Instead, the local generics extend
the ones in the host. See the material on host association and note the
"nongeneric" qualifier on much of it. To have a generic in a block
construct override instead of extend would be quite irregular and almost
certainly become a FAQ for people confused as to why it didn't work
"right". I seriously doubt that anyone actually intended a rule like
that.

Since all I'm trying to do is point out areas that do not appear to have
been adequately addressed by the block construct, I don't think it worth
my time to give a more detailed explanation - certainly of something as
messy as generics. I'm just going to stop with pointing out that it has
not been addressed. If you don't understand what the problem is, then
well... you probably aren't going to be in a position to adequately fix
it either. No, the simple answer you give above doesn't come close to
the mark.

Jim Xia

unread,
Sep 10, 2009, 10:48:24 PM9/10/09
to

> Generics are different from other names - very different. You can build
> up a generic with pieces from multiple scoping units. You can inherit
> part of it from a host, import part via USE, and declare part locally.
> Locally declared generics do *NOT* override ones from a host - at least
> not anywhere else in the language. Instead, the local generics extend
> the ones in the host. See the material on host association and note the
> "nongeneric" qualifier on much of it. To have a generic in a block
> construct override instead of extend would be quite irregular and almost
> certainly become a FAQ for people confused as to why it didn't work
> "right". I seriously doubt that anyone actually intended a rule like
> that.


I never said you (or I) had to agree with all the rules put in the
standard. I even don't agree with the intention of some the stuff put
in the standard. The best route for now is to submit a comment on FCD
and let standard committee to decide. But the citation is clear to me
what it means -- sorry.


> Since all I'm trying to do is point out areas that do not appear to have
> been adequately addressed by the block construct, I don't think it worth
> my time to give a more detailed explanation - certainly of something as
> messy as generics. I'm just going to stop with pointing out that it has
> not been addressed. If you don't understand what the problem is, then
> well... you probably aren't going to be in a position to adequately fix
> it either. No, the simple answer you give above doesn't come close to
> the mark.


Seems so.

Cheers,

Jim

Richard Maine

unread,
Sep 10, 2009, 11:26:06 PM9/10/09
to
Jim Xia <jim...@hotmail.com> wrote:

> I never said you (or I) had to agree with all the rules put in the
> standard. I even don't agree with the intention of some the stuff put
> in the standard. The best route for now is to submit a comment on FCD
> and let standard committee to decide. But the citation is clear to me
> what it means -- sorry.

Have you actually looked at the other equally clear and directly
contradictory citations? Such as all the ones about how all the generic
declarations in a scoping unit work - and which do not have exceptions
for generic declarations in blocks that are also in the scoping unit?
Having strange things in the standard is one matter; having direct
contraditions is another. See for example 12.5.5 (resolving named
procedure references) which is stuffed full of quite explicit mention of
scoping units. Dang, it is almost hard to find a sentence in 12.5.5 that
doesn't have the term "scoping unit". All of that material in 12.5.5
which directly contradicts the above mentioned citation, which says
(apparently "clearly" even) that specifications in the same scoping unit
have different results depending on whether they are in a block
construct. But 12.5.5 equally clearly says that it does not depend on
that, but only on what scoping unit the specifications are in. Lots of
luck in rewriting 12.5.5 to accomodate another level of dependency in
addition to scoping units. It is already a very messy part of the
standard - one that has gone through multiple major error fixes,
interpretation requests, etc. It is one of the pieces that I can't
answer any but the most trivial questions about except by opening the
standard and going through it line by line. (And sometimes I still get
it wrong). I do think I managed to craft a bit of simplification of this
in the F2003 handbook, but that took an awful lot of work.

This kind of thing is what integration of the standard is about. It is
also the kind of thing that I spent a *LOT* of time on as editor of f95
and f2003. (Embarassing how much I still missed). In evaluating the
consistency of the standard, you can't just read a single sentence in
the standard and stop there. You have to check that there aren't
contradictions elsewhere. Having the standard internally disagree with
itself is not just a question of whether I like the material or not.
Having internal contradictions in a standard is seriously bad. Sometimes
the internal contradictions are simply fixed, perhaps being just that
the edits for something missed one spot. I don't see such a simple fix
for this one; I think the contradictions go right to the core.

I gave up on submitting formal comments. My last one was pretty much
blown off in a way that doesn't much invite further effort along those
lines. I got some private expressions of emphatic agreement, but the
official response just amounted to "that's what we decided to do and we
aren't going to change our minds", along with "I should have voiced my
objections several years before the supporting data was available."

It is fairly evident to me that no comments are going to change the
course of matters bigger than this one in f2008. A majority appears to
have decided that coarrays are so critical to get into the Fortran
standard that they override all other considerations (including the core
parts of what I considered the Fortran standard to be for).

My understanding is that technical changes can't be made at this stage
anyway. Only things on the order of typographical fixes are allowed.
This is definitely not a typographical matter. So fixing it would kick
the standard back to a point several years earlier in the process. I
happen to think that would be a good idea, but I've got a notion how
well it would go over with the "coarrays as soon as possible regardless
of the problems" crowd.

Perhaps the Brits can pick this up as a technical reason to vote no.

0 new messages