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.
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.
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.
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:
a
as BYTE
and assigns the value 5
to it.a + 300
is evaluated. Since 300
is an INT
, the expression will be evaluated as INT
, resulting to 305
.a
. The number 305
can't be assigned to a BYTE
, so it will be truncated to 8 bits.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 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:
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 are similar to arrays in CBM BASIC.
DIM
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
There are three scopes in XC=BASIC:
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 SUB
s and FUNCTION
s), 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
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 (37-74 bytes, depending on target machine), 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.