Hi all (who read this). I have a question. Hope someone can help me. Is the following allowed or not in fortran 90:
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.
chzh...@sun.ssc.upenn.edu (Chunhui Zhang) writes: > Hi all (who read this). I have a question. Hope someone can help me. Is > the following allowed or not in fortran 90:
> 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
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. 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).
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. ===================================
It is, as Richard thought it might be, an automatic array. See also "Fortran 90/95 Explained", Section 6.4.
chzh...@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.
> 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.
-- 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
> 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. 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).
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.
> 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.
"Richard Maine" <nos...@see.signature> wrote in message
news:ueithplrsd.fsf@altair.dfrc.nasa.gov... | | "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."
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).
> I myself use Compaq's extension AUTOMATIC for such > arrays just to emphasize nature of such variables,
<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..
For example, I have a lot of lengthy local string variables throughout; currently they cannot be ALLOCATABLE, =================================================
"Jugoslav Dujic" <jdu...@yahoo.com> writes: > 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.
-- 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
_________ "David Frank" <dave_fr...@hotmail.com> wrote | | "Jugoslav Dujic" <jdu...@yahoo.com> wrote in message | news:9gv3hk$e0p$1@zmaj.etf.bg.ac.yu... | > I myself use Compaq's extension AUTOMATIC for such | > arrays just to emphasize nature of such variables, | | 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)..
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.
> I'm afraid you're wrong -- it does. There's a compiler switch to > set variables default to AUTOMATIC.
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..
> [...] For example, automatic > might imply re-initialization at each call. Yes, I'd like > that level of control also.
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?)
"Richard Maine" <nos...@see.signature> wrote |<snip> | 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 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 Dujic" <jdu...@yahoo.com> writes: > 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.
-- 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
Richard Maine wrote: > "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 ?
Toon Moene <t...@moene.indiv.nluug.nl> writes: > Richard Maine wrote: > > "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 hate to mention names because I'll forget one. > Hey ! You forgot me ;-)
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!
-- 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
"Richard Maine" <nos...@see.signature> wrote in message
news:ueelsc1hsi.fsf@altair.dfrc.nasa.gov... | "Jugoslav Dujic" <jdu...@yahoo.com> writes: | | > 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.
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).
<jdu...@yahoo.com> wrote: >"Richard Maine" <nos...@see.signature> wrote in message >news:ueithplrsd.fsf@altair.dfrc.nasa.gov... >| >| "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."
>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.
>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).
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.
> - 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).