Previous: , Up: Programming   [Contents][Index]


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.


Previous: , Up: Programming   [Contents][Index]