SUBROUTINE EX()
INTEGER A(N)
.....
.....
END SUBROUTINE
where N is a global variable(integer) defined outside the subroutine which
can change but is always positive. Some people say that's not allowed and
I have to use allocatable array.
Roughly speaking, yes it is allowed. This is what is called an automatic
array. What is the alleged basis for saying that it is disallowed? I
certainly can't imagine any. Perhaps the "some people" are being confused
by f77 extensions. Neither automatic nor allocatable were allowed in f77.
If you want a more precise answer, you will have to phrase a more precise
question. Specifically, there is no such thing as a "global variable",
so the question as given doesn't make sense, strictly speaking. I've
tried to give it a sensible interpretation, but it is quite possible
that the whole problem is in the translation of what you said to what
you mean.
For example, you show no ellipsis before the integer statement. If
you literally mean that, then there are evidently no USE statements in
the subroutine, so you must not mean module variables. If you mean
COMMON variables, and if the COMMON statement is after the integer
statement, then that is a problem. That would be illegal, but would
be simply solved by moving the COMMON statement earlier - it doesn't
require changing to allocatable.
The other possible interpretation of "global variable" would be
something inherited from the host scoping unit if this were an
internal subroutine. That would be fine.
The "some people say that's not allowed" strikes me as also a bit
vague. One often gets a bit more specific citation than that.
Is it possible that by "not allowed" they mean that it is disallowed
by some requirement other than the standard? For example, allocatable
arrays give you more options in error handling, so it is concievable
that some particular coding standard might disallow automatic arrays.
If so, that would be a completely different question than whether
the standard allows them.
--
Richard Maine | Good judgment comes from experience;
email: my last name at host.domain | experience comes from bad judgment.
host: altair, domain: dfrc.nasa.gov | -- Mark Twain
SUBROUTINE EX()
USE DATAMDL
INTEGER A(N)
.....
.....
END SUBROUTINE
where N is defined in module DATAMDL. The guy who said this is not
allowed said one can not define an array with dimension specified with a
variable. I compiled and ran my program which uses this without a
problem. I also read the programmer's guide and it seems to be allowed. I
just need a definite answer (for my boss who listens to the other guy and
believes he is a pro).
--
> Thanks answering my question, Richard. Let me clear it up a little bit. I
> actually meant N is a variable defined in a data module. Should be:
>
> SUBROUTINE EX()
> USE DATAMDL
> INTEGER A(N)
> .....
> .....
> END SUBROUTINE
>
> where N is defined in module DATAMDL.
That's fine.
> The guy who said this is not allowed said one can not define an
> array with dimension specified with a variable. I compiled and ran
> my program which uses this without a problem. I also read the
> programmer's guide and it seems to be allowed. I just need a
> definite answer (for my boss who listens to the other guy and
> believes he is a pro).
The guy is "obviously" (in my estimation) remembering f77, where this
was true. Slightly unusual for him to ackowledge the existance of
modules and allocatable arrays, but not of automatic arrays.
Automatic arrays were fairly common (though not universal) as an f77
extension. Several f77 compilers allowed them. I'd say they were
more common than allocatable arrays (which your "pro" did seem to
acknowledge) as an f77 extension. Modules, on the other hand, are a
"very" f90 feature. You'll never find them as an f77 extension
(anyway, I've never seen them done as such). It's too major a change
for an extension. By the time a vendor does that, they go ahead and
do f90 as a whole. Indeed, there was at least one case of a vendor
that claimed to have an f90 compiler without actually having gotten
around to doing modules. (The f90 label was basically just a
marketting lie - the compiler would more honestly have been labelled
as f77 with some f90 extensions).
This isn't a subtle enough point that I'd normally bother even
dragging out the standard for a citation. I don't think that anyone
could actually read the standard (or any of the texts about it) and
come to the conclusion that this wasn't allowed. But since you do ask
for a definitive answer, the really definitive source is the standard,
so I'll go there instead of just starting an "is so. is not. is so..."
style of argument.
From the f95 standard. The <> indicates bnf terms (set in italic in the
standard), and the <<>> indicates a definition (set in bold in the standard).
"5.1.2.4.1 Explicit-shape array
... R516 <upper-bound> is <specification-expr>
...
An <<automatic array>> is an explicit-shape array that is declared in a
subprogram, is not a dummy argument, and has bounds that are
nonconstant specification expressions."
The "nonconstant" bit should be a pretty string hint that variables are
allowed. I am *NOT* going to copy the whole definition of specification
expression from 7.1.6.2. It takes over a page of the standard, including
the definition of <restricted-expr> (which turns out to be most of the
"guts" of the definition). The critical part for current purposes, is
"...each primary is...
(4) A variable that is made accessible by use or host association or..."
That would seem to pretty unambiguously (and definitively) include your
case.
I can't, at a quick skim, find an example in the standard that quite
matches your code, but I can come pretty close. Note 5.11 shows an
automatic array with the dimension passed as a dummy argument (whereas
yours is via a USE). Note that only the dimension is a dummy
argument; the array itself isn't. If the array were a dummy argument,
it would just be an adjustable array, as was allowed in f77 (and f66,
for that matter). A similar example is in C.11.14, Automatic and
allocatable arrays:
"...automatic arrays, created on entry to a program and destroyed
on return.... The declarations
SUBROUTINE X (N, A, B)
REAL WORK (N, N); REAL, ALLOCATABLE :: HEAP (:, :)
specify an automatic array WORK and an allocatable array HEAP...."
That definitive enough?
P.S. As editor of the f95 standard, I ought to also count as a "pro",
but I don't like to argue on that basis. It has too much of a
"pissing contest" flavor, so I'll try to present actual citations
instead of just declaring it to be so because I said so.
I learned early on that absolute statements like "you can not do that" are, in general, a
no-no. But, back then when I was still unconsciously incompetent, I was suffering from a
superiority complex :o\ Fellow students and final exams / programming assignments cured
me of that...... pretty much :o)
FWIW, I use the above sort of thing all the time and it works just fine. You can also do
nifty stuff like:
SUBROUTINE EX( B )
INTEGER, DIMENSION( : ) :: B
INTEGER, DIMENSION( SIZE( B ) ) :: A
.....
.....
END SUBROUTINE
cheers,
paulv
--
Paul van Delst A little learning is a dangerous thing;
CIMSS @ NOAA/NCEP Drink deep, or taste not the Pierian spring;
Ph: (301)763-8000 x7274 There shallow draughts intoxicate the brain,
Fax:(301)763-8545 And drinking largely sobers us again.
Alexander Pope.
Richard Maine a écrit :
> chz...@sun.ssc.upenn.edu (Chunhui Zhang) writes:
>
> > Thanks answering my question, Richard. Let me clear it up a little bit. I
> > actually meant N is a variable defined in a data module. Should be:
> >
> > SUBROUTINE EX()
> > USE DATAMDL
> > INTEGER A(N)
> > .....
> > .....
> > END SUBROUTINE
> >
> > where N is defined in module DATAMDL.
>
> That's fine.
>
> An <<automatic array>> is an explicit-shape array that is declared in a
> subprogram, is not a dummy argument, and has bounds that are
> nonconstant specification expressions."
>
> The "nonconstant" bit should be a pretty string hint that variables are
> allowed.
A little more from the standard :
The bounds of such an array are unaffected by any redefinition or
undefinition
of the specification expression variables during execution of the procedure.
That is to say : the array take its shape and keep it until the end of the
procedure.
Claude Simon
Me again, Richard :-). I think that it would be nice to
have keyword AUTOMATIC which would (a) clarify the memory
class of such object and (b) be a counterpart to SAVE.
The language does have SAVE where it is the default
in most compilers -- I know that standard doesn't say
so but it is the common producers' practice -- while
the contrary isn't allowed.
I myself use Compaq's extension AUTOMATIC for such
arrays just to emphasize nature of such variables,
i.e.
subroutine foo()
use foomod, only: foodim
integer:: ilocal(foodim)
...
now, how do you know if foodim is PARAMETER or variable
if you don't look in foomod? Wouldn't it be nicer to
write:
integer, automatic:: ilocal(foodim)
Moreover, explicit allowance of AUTOMATIC semantic
could lead to some memory sparing. For example, I have a lot
of lengthy local string variables throughout; currently they cannot
be ALLOCATABLE, so they are implicitly SAVE (they're
mostly initialized). Wouldn't it be simpler just to declare them
AUTOMATIC and let them live on the stack? (Btw, I'm not sure how
frequent ALLOCATE/DEALLOCATE affects memory fragmentation).
Regards
Jugoslav
<snip>
> Moreover, explicit allowance of AUTOMATIC semantic
> could lead to some memory sparing. For example, I have a lot
> of lengthy local string variables throughout; currently they cannot
> be ALLOCATABLE, so they are implicitly SAVE (they're
> mostly initialized). Wouldn't it be simpler just to declare them
> AUTOMATIC and let them live on the stack? (Btw, I'm not sure how
> frequent ALLOCATE/DEALLOCATE affects memory fragmentation).
>
Lest readers mis-understand, CVF does NOT default to SAVE, therefore making
the need for its
AUTOMATIC keyword mostly un-needed, (I myself cant recall EVER needing it)..
re: let them "live" on the stack ??
On the surface that seems to be a oxymoron, since automatic variable stack
allocations are
"free"ed on subroutine exit whether DEALLOCATE is used or not..
AFAIK initializing strings that are declared SAVE is a 1-shot operation
handled by the
compiler (but it some cases it may be runtime 1-shot, I'm not sure)..
in either case your program will run faster if such arrays are statically
initialized, and not initialized
on each subroutine entry..
--
> Me again, Richard :-). I think that it would be nice to
> have keyword AUTOMATIC which would (a) clarify the memory
> class of such object and (b) be a counterpart to SAVE.
Me too.
Indeed, I think that there ought to be a way to
explicitly declare *ALL* attributes, including several others
that you can now declare only by the absense of declaration
otherwise. For example, I'd like to be able to declare
that something is scalar. Right now you can't do that and thus
can't guarantee that there isn't a dimension statement hidden
away in some include file. And I'd like to be able to
declare that something is a variable (instead of, for example,
a function). Perhaps just an explicit declaration that there
are no other attributes from separate statements could do much
of this.
I'll admit that my desire expressed in the above para doesn't
quite cover the SAVE/AUTOMATIC case because automatic implies
more than just the absense of save. For example, automatic
might imply re-initialization at each call. Yes, I'd like
that level of control also.
But I don't always get all my wishes. This one is still on my list.
Perhaps next time around. It isn't after all, a major capability
that should have lots of implementation or other complications.
I'm afraid you're wrong -- it does. There's a compiler switch to
set variables default to AUTOMATIC.
| re: let them "live" on the stack ??
| On the surface that seems to be a oxymoron, since automatic variable stack
| allocations are
| "free"ed on subroutine exit whether DEALLOCATE is used or not..
Sure they are, but you cannot DEALLOCATE something that isn't
ALLOCATABLE. And you cannot force something to be automatic
under current standard. I meant "live" in context "...until
they die when the procedure is exited".
| AFAIK initializing strings that are declared SAVE is a 1-shot operation
| handled by the
| compiler (but it some cases it may be runtime 1-shot, I'm not sure)..
| in either case your program will run faster if such arrays are statically
| initialized, and not initialized
| on each subroutine entry..
Correct, but speed is not the topic I addressed -- it's memory.
SAVE should speed up the things a bit (no operations for
allocation/deallocation, and, more critical, no need for
re-initialization). My application (large Win32 project with
lots of data inside) takes 1MB less virtual memory (~12:11 MB)
when compiled with "variables default to AUTOMATIC" switch.
Even if these 8% memory save is not critical, I'm advocating
AUTOMATIC attribute for more or less the same purpose as INTENT
arguments exist -- they clarify the intended use of the variable
as local and temporary. Even if most compilers use default SAVE
semantics, I still use SAVE keyword for the same reason
(disregarding potential portability issues) -- it emphasises
that the variable is to be reused on next entry.
Jugoslav
You are right, dont know why I said otherwise...
But I think the current standard (in having a SAVE but not a AUTOMATIC ) is
instructing anyone
examining a source to assume AUTOMATIC is the default in the absence of a
SAVE attribute..
I call that property INVARIANT. An INVARIANT symbol
differs from a PARAMETER in that it is initialized at each
entry to its scope (and the initialization expression can
involve procedure arguments, MODULE variables, etc.),
but must not be defined, redefined, or become undefined
in the code - the initialization expression is the one and
only place the value is defined.
The F2K proposal actually has a way to define these (obviously
not with the INVARIANT keyword). I think the feature is called
and ASSOCIATE block, but I don't remember offhand. The usual
thing done with such blocks will be to rename components of
derived data types, but symbols associated with unassignable
expressions will be invariant in the above sense. I will find
that quite useful. (Can ASSOCIATE define a symbol with a
constant?)
--
J. Giles
I think I owe you a clarification: I'm addressing you because
you seem to be the only person from the commitee which participates
in CLF (and sometimes regarded as "culprit on duty" :-( -- it's
direct translation of a Serbian phrase, don't know the English
equivalent).
As you once thoroughly explained, one can't expect too
much from this method of expressing wishes -- but it costs me
very little to do it... and it has a potential of attracting
different opinions on pros and cons for certain language
features. I'm aware that you don't have a magic wand... especially
after you explained the mechanism of commitee's decision
process.
However, my feeling is -- and my personal opinion is that
it is shared among many CLF participants -- that there's
a jungle in the Fortran compilers market regarding
various extensions introduced by different vendors.
Maybe that's because the market, though small, is more
competitive than elsewhere in the IT -- there's no
dominant product on the market (though David Frank
would probably object this statement :-)) which would impose
a de facto standard and virtually force the commitee
to accept these solutions whether they like it or not.
Microsoft, for example, often forced solutions from
their product to be accepted in ANSI C++, Sun in Java etc.
The situation here is more liberal, but I'm afraid it
leaves lots of issues unadressed and left to vendors
to solve them as they feel like -- and thus causing a high
level of unportability.
I'm aware of the fact that Fortran is primarily considered as a
"number-crunching" language and that the most of the Standard
is related to purposes related to that. It's just my opinion that
I'd like it to move towards a more general purpose language. I
deem it a pity that there's no standard solution for things
like:
- how to dereference a C pointer
- how to force an argument to be passed by value
- how to declare that the calling convention is __stdcall or __cdecl
- how to declare a variable VOLATILE, i.e. changeable out
of scope of the current process
- how to read command-line arguments
- how to create a directory
...
Some of the issues above, strictly speaking, are platform-dependent;
however, it's a fact that __stdcall exists on some platforms, that
all platforms I know about do have command-line arguments and
directories as a concept; (there are probably some that don't but
I don't think they are even a recognizable minority). These terms
don't exist in vain -- those are real-life problems and it's my expectation
that they're covered by some kinda standard or at least a recommendation.
Uh, this became a lament and quite off topic --
sorry if I was too extensive -- just had to push it out of myself.
Jugoslav
> I think I owe you a clarification:
No "clarification" needed. Comments accepted.
> you seem to be the only person from the commitee which participates
> in CLF
There are several others also. I'm just more loud-mouthed than some.
(This characterization applies at the J3 meetings also. :-()
I hate to mention names because I'll forget one, but Dan Nagle
and Dick Hendrickson also post here with fair regularity. A few
others post on occasion. And I'd venture a guess that perhaps
half of the committee at least lurks here.
> - how to declare a variable VOLATILE, i.e. changeable out
> of scope of the current process
> - how to read command-line arguments
> - how to force an argument to be passed by value
The above 3 are in the f2k draft (value having been a pretty late
addition - at least insofar as it can be used for things in addition
to C calls). Yes, I'm aware that being in the f2k draft isn't the
same as yet being standardized and widely implemented.
> - how to dereference a C pointer
I (and some others) tried to get that. (I wanted to be able to
construct a Fortran pointer using a C pointer for the address, and
getting the type and shape information separately). Met resistance,
at least for now.
> - how to declare that the calling convention is __stdcall or __cdecl
I don't actually even know what that means. Yes, I've heard the words
before, and I'm sure I could look them up easily enough. But it's
not something I actually know (or much feel like pawing around in).
> - how to create a directory
Well, C interop will at least give a way, albeit sort of ugly.
It's hard to draw the boundary between what stuff to replicate
in Fortran and what stuff to just treat by saying that it is
available through C interop. There has to be a boundary somewhere.
I'd waffle as to which side of it I'd think this belonged on.
> sorry if I was too extensive -- just had to push it out of myself.
No apology needed. Seems on topic and expressed without flaming.
> "Jugoslav Dujic" <jdu...@yahoo.com> writes:
> > you seem to be the only person from the commitee which participates
> > in CLF
>
> There are several others also. I'm just more loud-mouthed than some.
> (This characterization applies at the J3 meetings also. :-()
> I hate to mention names because I'll forget one.
Hey ! You forgot me ;-)
Oh, BTW, perhaps someone is interested in the USENIX 2002 "FREENIX"
track ?
See http://www.usenix.org/events/usenix02/cfp/freenix.html
As I'm on the program committee, we might get some Fortran related stuff
in :-) :-)
Cheers,
--
Toon Moene - mailto:to...@moene.indiv.nluug.nl - phoneto: +31 346 214290
Saturnushof 14, 3738 XG Maartensdijk, The Netherlands
Maintainer, GNU Fortran 77: http://gcc.gnu.org/onlinedocs/g77_news.html
Join GNU Fortran 95: http://g95.sourceforge.net/ (under construction)
I did that on purpose so that I'd be sure to be right when I
said I'd forget one....guess that line won't fly, huh? :-)
Drat!
Oh, I knew about Dan, but not about Dick and Toon -- they're
pretty silent about that :-). It seems that they let you do
the job of an unoficial spokesman :-).
| > - how to declare that the calling convention is __stdcall or __cdecl
|
| I don't actually even know what that means. Yes, I've heard the words
| before, and I'm sure I could look them up easily enough. But it's
| not something I actually know (or much feel like pawing around in).
I guess these are mostly from Wintel world (names are from Windows C's).
__stdcall is also referred to as Pascal. Roughly, __stdcall means
that args are pushed from right to left, callee cleans the stack and
scalar arguments default to by-value. __cdecl is C calling convention,
i.e. args are pushed from left to right, caller cleans the stack and
args also default to ByValue. The latter enables C to provide optional
arguments. You may imagine that mixing those two may lead to nasty
stack corruptions. I'm not too familiar with UNIX, but I think that
__cdecl is used there throughout (except that for Fortran args default
to reference/pointer).
At Wintel, C compilers use __cdecl, VB and Delphi __stdcall,
MS C++ __thiscall (__cdecl, plus this passed as first hidden
argument plus a complex name mangling), Borland C++ another
variant of __thiscall, and CVF __stdcall with Fortran features
(reference by default plus hidden string lengths).
Jugoslav
I am generally sympathetic to the idea of having explicit keywords for
attributes that are now implied by the lack of contradictory
attributes, but I also have to point out that the existence of an
AUTOMATIC keyword wouldn't necessarily have any of the effects
Jugoslav is expecting.
If a procedure is not RECURSIVE, then a processor can ensure that it
will never need more than one instance at a time of the variables
declared within it. Those variables in such a procedure with
constant attributes (e.g., array bounds) will occupy the same amount
of storage each time the procedure is executed, so a legitimate
implementation is to allocate the storage for such variables
statically. From the perspective of the standard, this is
indistiguishable from allocating and deallocating this storage each
time, but getting the same chunk of storage each time (perhaps because
it is exactly the right size) and never using it for anything else
(perhaps because of storage fragmentation).
There are some differences between such variables and those with the
SAVE attribute (e.g., in the handling of default initialization), but
with or without the explicit keyword AUTOMATIC, the impact on memory
usage could be the same, because variables without the SAVE attribute
are already expected to behave as if they were declare AUTOMATIC.
Processors might, _as_an_extension_, choose to handle memory
management differently for variables implicitly automatic and those
explictly AUTOMATIC, but that is nothing the standard would guarantee,
and it is thus no more portable than the compiler switches currently
available to you.
-Kurt
[...]
> - how to declare that the calling convention is __stdcall or __cdecl
Those are Windows-specific things which have no place in _any_
language standard (they are not in the C and C++ standards either).
However, one could think of a generic feature like C++'s extern "C"
(which AFAIK vendors could extend to things like extern "stdcall"
without violating the standard - it's just that the non-standard
__stdcall syntax already existed, and C has no extern "..." syntax
anyway).
[...]