language rules question: using a (passed in) parameter to define a parameter

language rules question: using a (passed in) parameter to define a parameter

Post by BenR » Fri, 27 Jul 2007 08:05:38


Hello,
I am working on a program where we send a variable defined as a
parameter as an argument to a subroutine. In the subroutine, when I
try to define another parameter using the parameter that was passed
in, I get the following error:

Error: This symbol must be a defined parameter or an argument of an
inquiry function that evaluates to a compile-time constant.
This is Compaq Fortran.

so here is the structure:

subroutine sub(x) !x was a parameter in the calling function
integer x,y
parameter(y=x+5)
...
end sub

Anyone know why this is behaving like this?
Thanks!
 
 
 

language rules question: using a (passed in) parameter to define a parameter

Post by nospa » Fri, 27 Jul 2007 08:21:05


Stop right there. There is no such thing. This is important. A parameter
is *NOT* a variable. Period. It is a named constant, which is not the
same thing. In particular, it cannot vary.


The comment reveals the essential issue that you are overlooking. The
subroutine doesn't "know" that x was a parameter in the calling
function. In fact, for all the subroutine "knows", it might end up
getting called by other procedures that you haven't even written yet.

A dummy argument is a variable. It is not a parameter, even if the
associated actual argument is one. If the associated actual argument is
a parameter, then it will not be valid to redefine the variable, but it
still counts as a variable.

Parameters must be known at compile time. In particular, they must not
depend on variables. The fact that you happen to know that this
particular variable will always have the same value, which comes form a
parameter actual argument doesn't matter. That's your personal
knowledge, rather than the rules of the language.

The actual technical requirement is that the parameter must be defined
by an "initialization expression". The precise technical definition of
"initialization expression" is a bit complicated and has several tricky
parts, some of which vary among versions of the standard. But this isn't
one of the tricky parts. That it can't depend on a dummy argument (or
any other variable) is straightforward.

The "must be done at compile time" bit is a reasonable intuitive guide
to at least the simple cases, including this one. You just also have to
understand the separate compilation model - that the compiler doesn't
get to deduce properties of the dummy argument form your comment, or
from anything else other than the subroutine itself.

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

 
 
 

language rules question: using a (passed in) parameter to define a parameter

Post by BenR » Sat, 28 Jul 2007 04:14:18


Thank you for your explanation. I sincerely appreciate it.

If you wouldn't mind, could you recommend a preferred method of
defining a parameter in once place and using it as a parameter in many
places? Would a module be the way to go? If I were stuck in F77
(this program is in a limbo), I know of common blocks but I don't
think you can make them immutable like parameters. My second guess
would be to make a header file, define the parameter in one place
there, and then USE the header at the top of all subroutines that need
the parameter.

I am sorry, my college fortran class was heavy on the practice and
light on the theory, so the concept that things you name such as
"integer x" are not all called variables was foreign, as was the term
"initialization expression".

Thanks!
-Ben
 
 
 

language rules question: using a (passed in) parameter to define a parameter

Post by nospa » Sat, 28 Jul 2007 04:57:11

enR < XXXX@XXXXX.COM > wrote:


Definitely. That's the easy and "obvious" way in f90.


Correct. COMMON can only have variables. Parameters aren't variables.
Basically, a parameter might not even exist in memory at run-time. It is
a compile-time concept. In many situations, the value of the parameter
will also end up somewhere in memory. For example, if you pass it as an
actual argument, there will need to be a memory location for that actual
argument; but in some sense, that location is just a temporary copy of
the value of the parameter, rather then being the parameter itself.


Yes, that would be what to do if you are stuck with Fortran 77, except
for some minor quibbles, namely

USE is what you do with modules. I might have thought you meant to "use"
it in a more generic sense, but your capitalization sure makes it sound
like you mean a USE statement. A USE statement is only for modules and
will not be found in any f77 compiler, even as an extension.

What you can do in most f77 compilers is INCLUDE a source file. INCLUDE
is not strictly f77 either, but almost all f77 compilers that you are
likely to run into these days have it as an extension. Some earlier f77
compilers didn't, but they are not compilers that you are likely to
find. The term "header file" isn't really a Fortran term, though the
concept is understood and some people probably call them that. You are
more likely to see them called something like "include files", though it
is the same concept.

One thing important to understand about include files (or header files)
is that it is purely a textual inclusion of the source code. There is no
particular connection between different scoping units just because they
include the same files. In particular, declaring a variable in an
include file does not magically make it the same variable in all places
that include the file. Likewise, when you declare a parameter in an
include file, you will in some sense have a different parameter (of the
sam ename) in each scoping unit that includes the file. But all these
different parameters will have the same value, so the distinction is
mostly academic.

One question is whether you actually need the things in question to be
paameters. Perhaps you do; I don't have enough data to tell. If they
don't have to be parameters, then there are other options.


The gory details of initialization expressions are messy and, for the
most part, you don't need to know them, but can just remember the
principle that they must be known at compile time.

A lot of people get tripped up by the fact that the statement

integer x

doesn't mean that x is a variable. I find it an unfortunate and
historical oddity that Fortran doesn't actually have a direct way of
declaring something to be a variable. The only ways are indirect, such
as declaring an attribute that only a variable can have (SAVE comes to
mind, but it isn't allowed in all cases), or most commonly, just by not
declaring that it is something other than a variable. I would prefer at
least the option of a direct and positive declaration rather than the
indirect or negative forms available.

That declaration means only that x, whatever it is, has type integer. X
might be a variable, a parameter, or a function. I think those are the
only possibilities.

--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience come
 
 
 

language rules question: using a (passed in) parameter to define a parameter

Post by Craig Powe » Fri, 03 Aug 2007 03:39:03


It might be a confusion with C and C++, where variables with the "const"
attribute behave the way he's trying to make PARAMETERs behave -- you're
allowed to initialize them with a runtime-evaluation expression, and the
"const" is just a promise (enforced by the compiler) that you will not
attempt to modify the value after initializing it.
 
 
 

language rules question: using a (passed in) parameter to define a parameter

Post by BenR » Sat, 04 Aug 2007 07:23:23

n Jul 26, 3:57 pm, XXXX@XXXXX.COM (Richard Maine) wrote:

Richard,
Thank you very much for the explanation. You were correct, I should
have typed "INCLUDE" instead of "USE". I appreciate the time you have
taken to enlighten me.
Regards,
Ben