asymptote: Static
6.15 Static
===========
Static qualifiers allocate the memory address of a variable in a higher
enclosing level.
For a function body, the variable is allocated in the block where the
function is defined; so in the code
struct s {
int count() {
static int c=0;
++c;
return c;
}
}
there is one instance of the variable 'c' for each object 's' (as
opposed to each call of 'count').
Similarly, in
int factorial(int n) {
int helper(int k) {
static int x=1;
x *= k;
return k == 1 ? x : helper(k-1);
}
return helper(n);
}
there is one instance of 'x' for every call to 'factorial' (and not for
every call to 'helper'), so this is a correct, but ugly, implementation
of factorial.
Similarly, a static variable declared within a structure is allocated
in the block where the structure is defined. Thus,
struct A {
struct B {
static pair z;
}
}
creates one object 'z' for each object of type 'A' created.
In this example,
int pow(int n, int k) {
struct A {
static int x=1;
void helper() {
x *= n;
}
}
for(int i=0; i < k; ++i) {
A a;
a.helper();
}
return A.x;
}
there is one instance of 'x' for each call to 'pow', so this is an ugly
implementation of exponentiation.
Loop constructs allocate a new frame in every iteration. This is so
that higher-order functions can refer to variables of a specific
iteration of a loop:
void f();
for(int i=0; i < 10; ++i) {
int x=i;
if(x==5) {
f=new void () { write(x); }
}
}
f();
Here, every iteration of the loop has its own variable 'x', so 'f()'
will write '5'. If a variable in a loop is declared static, it will be
allocated where the enclosing function or structure was defined (just as
if it were declared static outside of the loop). For instance, in:
void f() {
static int x;
for(int i=0; i < 10; ++i) {
static int y;
}
}
both 'x' and 'y' will be allocated in the same place, which is also
where 'f' is also allocated.
Statements may also be declared static, in which case they are run at
the place where the enclosing function or structure is defined.
Declarations or statements not enclosed in a function or structure
definition are already at the top level, so static modifiers are
meaningless. A warning is given in such a case.
Since structures can have static fields, it is not always clear for a
qualified name whether the qualifier is a variable or a type. For
instance, in:
struct A {
static int x;
}
pair A;
int y=A.x;
does the 'A' in 'A.x' refer to the structure or to the pair variable.
It is the convention in Asymptote that, if there is a non-function
variable with the same name as the qualifier, the qualifier refers to
that variable, and not to the type. This is regardless of what fields
the variable actually possesses.