Warning
You're browsing the old v2.x documentation. This version is no longer maintained. Click here to go the v3.x documentation.
Table of Contents
Variables
Variables in XC=BASIC are statically allocated memory areas that are assigned an identifier (name) and a type that can not be changed.
Variable definition
Variables don't need to be explicitly defined. The compiler will create the variable the first time it encounters them in a LET
, DIM
or DATA
statement.
Example:
let a = 1 rem -- a is now defined print a rem -- the following is invalid because b is used prior to being defined print b let b = 2
Fast variables
Since version 2.1, some variables can be placed on the zeropage for faster load/store operations. You can use the DIM
directive to define a variable as fast variable, for example:
dim myFastVar fast
This is limited however (max 15 bytes currently). The compiler will emit a warning if no more variables can be placed on the zeropage.
Types
The type of a variable is specified using a sigil that is appended to the variable name. If omitted, the variable will be recognized as integer. The following types are supported:
Type | Sigil | Numeric range | Size in bytes |
---|---|---|---|
Byte | ! | 0 to 255 | 1 |
Integer | # or none 1) | -32768 to +32767 | 2 |
Float | % | ±2.93873588E−39 to ±1.70141183E38 | 5 |
String pointer | $ | 0 to 65535 | 2 |
Type conversion
Implicit conversion
If different types take part of an expression, all members of the expression will be implicitly promoted to the larger type and a warning will be emitted in compile time. This means that:
- If at least one member of an expression is a float, every other members will be converted to float.
- Otherwise if at least one member of an expression is an integer, every other members will be converted to integer.
Example:
let anInt = 5 let anotherInt = 6 let aFloat% = 3.14 print anInt + anotherInt + aFloat% rem -- the above expression will return a float while anInt and anotherInt rem -- will be promoted to floats
The above program will compile fine, with a warning:
Warning: implicit type conversion in line 4
Implicit conversion from byte to integer does not emit a warning.
An important note about sub-expression casting
A parenthesized sub-expression is considered to be a single member of its parent expression. Implicit type casting does not apply to members of the sub-expression. Take the following code sniplet for example:
anInteger = 4 aByte! = 255 anotherByte! = 1 result = anInteger * (aByte! + anotherByte!)
You may expect that someByte
and anotherByte
will be converted to integers first and then their sum will be multiplied with anInteger
. This is not how it will work though. The expression will be evaluated as follows:
- The parenthesized expression is evaluated. Both of its members are bytes, so the whole expression (
aByte! + anotherByte!
) is evaluated as byte. The numbers are added up, and an overflow occurs (255 + 1 = 0) - The outer expression is an integer, because one of its members (
anInteger
) is an integer. So the other member (which is now evaluated to 0) is converted to an integer and the two factors are multiplied. The result is 0.
To solve this problem you have to explicitly cast at least one of the members of the sub-expression to integer and thus the compiler will implicitly convert the other member, too:
result = anInteger * (cast(aByte!) + anotherByte!)
Now the result will is 4 * (255 + 1) = 4 * 256 = 1024
.
Explicit conversion
You can use the CAST()
function to convert between different types. For example:
let aFloat% = 3.14 let anInt = cast(aFloat%) rem -- the above will print 3 let anInt = 3 let aFloat% = cast%(anInt) rem -- note you can't just "let aFloat% = anInt" let anInt = 256 let aByte! = cast!(anInt) rem -- the above will print 1 and you'll be warned of truncation
Constants
Constants are not variables in a sense that they do not reserve memory at all. However, you can use them just like a variable, except that they may not change value in runtime.
The benefit of using constants instead of variables are:
- Constants do not reserve space in memory
- Constants are faster to evaluate
Always prefer constants over variables, whenever possible. See the documentation for the CONST statement for more information.
Scope
Variables, constants and labels can be global or local.
Any variable or constant declared using a CONST
, LET
, DIM
or DATA
statement outside a PROC … ENDPROC
pair is considered to be a global variable and are only accessible within a procedure by using the global modifier (\
).
Any variable or constant declared using a CONST
, LET
, DIM
or DATA
statement inside a PROC … ENDPROC
pair, including the procedure's parameters, is considered to be a local variable and can only be accessed within that procedure.
Please see the documentation for the PROC ... ENDPROC statements for more details.