Skip to content

References

Positron edited this page Aug 3, 2017 · 1 revision

NOTE: At this time, due to lack of support for non-function references in the game engine, references to arrays and structure variables have the following restrictions:

  • Only references to private arrays and structure variables can be assigned to variables and passed to functions.
  • References to arrays and structure variables cannot be shared between libraries. That means you cannot pass an array reference to another library, and you cannot use an array reference in, or returned from, another library.

Array references

element-type [] & var = reference ;

In C, when you specify an array, it "decays" into a pointer to the first element of the array. In BCS, something similar happens: when you specify an array, what you actually get is a reference to the array. You can then save that reference into a reference variable, or pass it to a function:

#library "reftest"

// Only references to private variables can be passed around to functions.
private int a[] = { 1, 2, 3 };
private int b[] = { 6, 5, 4 };

script "Main" open {
   PrintArray( a );
   PrintArray( b );
}

void PrintArray( int[]& array ) {
   foreach ( let int element; array ) {
      Print( d: element );
   }
}

Structure variable references

structure & var = reference ;

Similar to arrays, when you specify a structure variable, what you get is a reference to the structure variable:

#library "reftest"

struct NumberT {
   int value;
};

// Only references to private variables can be assigned to reference variables
// and passed around to functions.
private NumberT someNumber = { 123 };

script "Main" open {
   NumberT& number = someNumber;
   Print( d: number.value ); // Output: 123
   ChangeNumber( number );
   Print( d: number.value ); // Output: 321
}

void ChangeNumber( NumberT& number ) {
   number.value = 321;
}

Function references

return-type function( [parameters] ) [qualifiers] & var = reference ;

Similar to arrays and structure variables, when you specify a function, what you get is a reference to the function:

#library "reftest"

void F1() { Print( s: "F1() called" ); }
void F2() { Print( s: "F2() called" ); }

script "Main" open {
   void function()& f = F1;
   f(); // Output: F1() called
   f = F2;
   f(); // Output: F2() called
}

Nullable references

The null reference is an invalid reference. A nullable reference is a reference that can either be a valid reference or the null reference. Nullable references can only be assigned to variables of nullable reference type. A nullable reference type is marked with a question mark (?) instead of an ampersand (&):

script "Main" open {
   int[]? r = null;
   struct S { int a; }? r2 = null;
   void function()? r3 = null;
}
Null check

The null reference cannot be dereferenced. Everytime you use a nullable reference, the game will check the reference. If it is the null reference, an error will be reported in the console and the current script will be terminated:

script "Main" open {
   int[]? r = null;
   r[ 0 ] = 123; // Prints error and terminates script.
}
From nullable to non-nullable

A nullable reference cannot be assigned to a non-nullable reference variable. The !! operator confirms that a nullable reference is not the null reference by performing the above null check and returns the nullable reference as a non-nullable reference:

script "Main" open {
   static int a[] = { 1, 2, 3 };
   int[]? r = a;
   // `r` refers to a valid reference, so will succeed.
   int[]& r2 = r!!;
   r = null;
   // `r` no longer refers to a valid reference, so an error will be printed
   // and the script will be terminated.
   r2 = r!!;
}