1.35. Pointers

Felix supports pointers. The type of a pointer to T is denoted:
  &T
A pointer can be created by addressing a variable using the notation:
  &v
Pointers can be dereferenced using the usual syntax:
  *p
and there is the usual arrow notation:
  p->x
which means the same as
  (*p).x

Only variables, not values, are addressable. Pointers are used to implement assignment. You have seen many examples of assignment:

  var v : T;
  v = e;
What you didn't know was that the assignment operator is just syntactic sugar for the procedure call:
  set(&v,e);
This procedure is defined automatically for structs, unions, and function and procedure closures, that is, for Felix types; but you can define it manually for abstract types including primitives. The usual definition is:
  type T = "T";
  proc _set: &T * t = "*$1=$2;"
If you don't define a set method for a primitive type, Felix assumes the C++ assignment operator as above. WARNING: This is wrong in principle, since Felix cannot check such a function exists, if it doesn't, you will get an error at C++ compilation time instead of Felix compilation time. Be warned!

Note that all Felix primitives must be C++ assignable and implicitly default constructible, since in the generated code all values and variables are first declared without an initialiser and then assigned to.

It is important to note that in Felix, you can take the address of any variable, and safely pass the pointer around, without fear it will dangle: this includes pointers to function and procedure local variables.

This all works because Felix uses a garbage collector, but you should note that because the frame containing an object must be kept alive if there is a pointer into it, returning a pointer to a function local variable may prevent other local variables in the same frame from being destroyed.

Here is an example:

Start C++ section to tut/examples/tut143.flx[1 /1 ]
     1: include "std";
     2: 
     3: fun pone (): &int =
     4: {
     5:   var x : int = 1;
     6:   return &x;
     7: }
     8: 
     9: var p1 = pone();
    10: print (*p1); endl;
    11: *p1 = 2;
    12: 
    13: print (*p1); endl;
    14: 
End C++ section to tut/examples/tut143.flx[1]
You should note that Felix pointers consist of two C pointers: a pointer to the variable, and a pointer to the frame containing the variable. It is this frame pointer which the garbage collector tracks. Although Felix pointers do not have to be initialised, the frame pointer component of the representation is always initialised to NULL so that the garbage collector doesn't chase off into the wild blue yonder.