Quick start manual
Data types, variables, and constants
5-33
Variant types
The @ operator can also be used to assign an untyped pointer value to a procedural 
variable. For example,
var StrComp: function(Str1, Str2: PChar): Integer;
ƒ
@StrComp := GetProcAddress(KernelHandle, 'lstrcmpi');
calls the GetProcAddress function and points StrComp to the result.
Any procedural variable can hold the value nil, which means that it points to 
nothing. But attempting to call a nil-valued procedural variable is an error. To test 
whether a procedural variable is assigned, use the standard function Assigned:
if Assigned(OnClick) then OnClick(X);
Variant types
Sometimes it is necessary to manipulate data whose type varies or cannot be 
determined at compile time. In these cases, one option is to use variables and 
parameters of type Variant, which represent values that can change type at runtime. 
Variants offer greater flexibility but consume more memory than regular variables, 
and operations on them are slower than on statically bound types. Moreover, illicit 
operations on variants often result in runtime errors, where similar mistakes with 
regular variables would have been caught at compile time. You can also create 
custom variant types.
By default, Variants can hold values of any type except records, sets, static arrays, 
files, classes, class references, and pointers. In other words, variants can hold 
anything but structured types and pointers. They can hold interfaces, whose methods 
and properties can be accessed through them. (See Chapter 10, “Object interfaces”.) 
They can hold dynamic arrays, and they can hold a special kind of static array called 
a variant array. (See “Variant arrays” on page 5-36.) Variants can mix with other 
variants and with integer, real, string, and Boolean values in expressions and 
assignments; the compiler automatically performs type conversions.
Variants that contain strings cannot be indexed. That is, if V is a variant that holds a 
string value, the construction V[1] causes a runtime error.
You can define custom Variants that extend the Variant type to hold arbitrary values. 
For example, you can define a Variant string type that allows indexing or that holds a 
particular class reference, record type, or static array. Custom Variant types are 
defined by creating descendants to the TCustomVariantType class.
Note
This, and almost all variant functionality, is implemented in the Variants unit.
A variant occupies 16 bytes of memory and consists of a type code and a value, or 
pointer to a value, of the type specified by the code. All variants are initialized on 
creation to the special value Unassigned. The special value Null indicates unknown or 
missing data.










