Variables

XC=BASIC is a statically typed programming language which means that the type of a variable is known at compile time. All variables have a type and that type cannot change.

Defining Variables

In an XC=BASIC program, all variables must be defined before they're used. Either you define them using the DIM statement (this is called explicit definition) or the compiler will auto-define them in certain situations. The latter is called implicit definition.

Explicit Definition

The DIM statement may be used to explicitly define variables. Here are some examples of variable definition using DIM:

DIM enemy_count AS INT
DIM score AS DECIMAL
DIM gravity AS FLOAT
DIM name$ AS STRING * 16

Apart from the DIM statement, there are other cases where you may explicitly define a variable. You will learn about those later.

Note

Defining variable types by using sigils (the #, % and ! suffixes) is no longer supported in XC=BASIC. The $ character is allowed at the end of variable names for readability but the variable won't be defined as STRING just because the $ sign is there. You must use DIM to define Strings.

Implicit Definition

If an undefined variable is encountered by the compiler, it will try to define it silently. For example:

a = 5
PRINT a

The above program works because the compiler implicitly defines the variable a in the first line. But what will its type be? The compiler first checks the right hand side of the assignment, in this case the number 5. As stated previously, a number between 0 and 255 is best represented by the Byte type, and therefore the compiler will infer a to be of type Byte. This is called an inferred type because the compiler examines the expression and, using the above stated rules, decides which type best represents it.

This seems very convenient, but it is something you should generally avoid so that the compiler will not automatically assign data types you don't intend and/or produce results that are inaccurate yet hard to track down in code. Take the following example:

a = 5
a = a + 300
PRINT a

In CBM BASIC, where the only numeric type is FLOAT, you can safely expect the result to be 305. In XC=BASIC this is not the case. Let's break down the above example and see how the compiler will handle it:

  1. The compiler defines a as BYTE and assigns the value 5 to it.
  2. The expression a + 300 is evaluated. Since 300 is an INT, the expression will be evaluated as INT, resulting to 305.
  3. Now the result must be assigned to a. The number 305 can't be assigned to a BYTE, so it will be truncated to 8 bits.
  4. The result is 49.

Since, on the surface, the result does not make any sense to a human mind, it might be difficult to track down the problem. We can fix the above program by explicitly defining a as INT:

DIM a AS INT
a = 5
a = a + 300
' The result is: 305
PRINT a

Warning

It is recommended that you define variables explicitly rather than let the compiler guess their types to avoid issues like the example above.

Note

Unlike CBM BASIC variables, which are automatically initialized to 0, XC=BASIC does not provide any initialization of variables. This means that you cannot assume anything about the value of a variable until you have assigned some value to it. The initial value of a variable is simply whatever happens to be in the memory location XC=BASIC assigns to the variable.

Constants

Constants are simple textual labels that represent numeric values in compile time. When the compiler encounters a constant, it will replace it with the value it represents.

The benefits of using constants instead of variables are:

  • As opposed to variables, no memory is allocated for constants
  • Constants are faster to evaluate than variables

Note

Always use constants over variables whenever possible to save memory and speed up program execution. See the CONST keyword reference page for more information.

Arrays

Arrays are similar to arrays in CBM BASIC.

  • They must be explicitly defined in all cases using DIM
  • The maximum number of dimensions is 3

A few examples of defining arrays:

DIM cards(52) AS BYTE
DIM my_cards(5) AS BYTE
DIM matrix(5, 5) AS FLOAT

Accessing array members is done using the usual BASIC syntax:

DIM my_array(3, 3) AS LONG
x = my_array(0, 1)

Warning

Array indices are zero-based which means the first item's index is 0.

Warning

For performance reasons, array bounds are not checked at runtime. If you use an index that is out of the bounds, the result will be unpredictable.

DIM numbers(10) AS LONG
' This will compile fine but
' probably break your program because
' the last index in the array is 9.
i = 10
numbers(i) = 9999

Variable Scope

There are three scopes in XC=BASIC:

  • SHARED: the widest scope, a shared variable is visible in all Code Modules. A Code Module is a single source file (for example: program.bas). Learn more about Code Modules here.
  • GLOBAL: the variable is visible in the current Code Module (in the source file where it was defined).
  • LOCAL: the variable is only visible within the SUB or FUNCTION where it was defined.

If you define a variable outside a SUB or FUNCTION, it will be defined in the Global scope by default which means that it can be accessed from everywhere within that BAS source file (even from within SUBs and FUNCTIONs), but not from other files.

If you define a variable inside a SUB or FUNCTION, it will be defined in the Local scope of that SUB or FUNCTION and it won't be accessible from anywhere else.

Using the SHARED keyword in a DIM statement, you can make a variable visible from all Code Modules:

' This file is first.bas
' 'a' is a global variable in this file only
DIM a AS INT
' 'b' is a shared variable visible in other files as well
DIM SHARED b AS INT
a = 5
b = 10
INCLUDE "second.bas"
' Will print: 5
PRINT a
' Will print: 11
PRINT b
' This file is second.bas
' 'a' is a global variable in this file only
' It doesn't collide with the other 'a' in first.bas
DIM a AS INT
a = 6
' We can access 'b' from first.bas
b = 11

Fast Variables

If you define a variable as FAST, it will be reserved on the zero page, making it faster under the hood to reference and operate on. The space on zero page is limited (currently about 60 bytes), but that's enough space to supply a relatively generous number of FAST variables.

DIM FAST ix AS BYTE
FOR ix = 0 TO 255
  ' A very fast loop
NEXT

Note

When no more variables can be placed on the zero page, the compiler will emit a warning and ignore the FAST directive from then on.