Variables (Delphi)

From RAD Studio
Jump to: navigation, search

Go Up to Data Types, Variables, and Constants Index

A variable is an identifier whose value can change at run time. Put differently, a variable is a name for a location in memory; you can use the name to read or write to the memory location. Variables are like containers for data, and, because they are typed, they tell the compiler how to interpret the data they hold.

Declaring Variables

The basic syntax for a variable declaration is:

var identifierList:type;

where identifierList is a comma-delimited list of valid identifiers and type is any valid type. For example:

 var I: Integer;

declares a variable I of type Integer, while:

 var X, Y: Real;

declares two variables - X and Y - of type Real.

Consecutive variable declarations do not have to repeat the reserved word var:

    X, Y, Z: Double;
    I, J, K: Integer;
    Digit: 0..9;
    Okay: Boolean;

Variables declared within a procedure or function are sometimes called local, while other variables are called global. Global variables can be initialized at the same time they are declared, using the syntax:

var identifier: type = constantExpression;

where constantExpression is any constant expression representing a value of type type. Thus the declaration:

 var I: Integer = 7;

is equivalent to the declaration and statement:

 var I: Integer;
 I := 7;

Local variables cannot be initialized in their declarations. Multiple variable declarations (such as var X, Y, Z: Real;) cannot include initializations, nor can declarations of variant and file-type variables.

If you do not explicitly initialize a global variable, the compiler initializes it to 0. Object instance data (fields) are also initialized to 0. The contents of a local variable are undefined until a value is assigned to them.

When you declare a variable, you are allocating memory which is freed automatically when the variable is no longer used. In particular, local variables exist only until the program exits from the function or procedure in which they are declared. For more information about variables and memory management, see Memory Management.

Absolute Addresses

You can create a new variable that resides at the same address as another variable. To do so, put the directive absolute after the type name in the declaration of the new variable, followed by the name of an existing (previously declared) variable. For example:

   Str: string[32];
   StrLen: Byte absolute Str;

specifies that the variable StrLen should start at the same address as Str. Since the first byte of a short string contains the string length, the value of StrLen is the length of Str.

You cannot initialize a variable in an absolute declaration or combine absolute with any other directives.

Dynamic Variables

You can create dynamic variables by calling the GetMem or New procedure. Such variables are allocated on the heap and are not managed automatically. Once you create one, it is your responsibility ultimately to free the variable's memory; use FreeMem to destroy variables created by GetMem and Dispose to destroy variables created by New. Other standard routines that operate on dynamic variables include ReallocMem, AllocMem, Initialize, Finalize, StrAlloc, and StrDispose.

Long strings, wide strings, dynamic arrays, variants, and interfaces are also heap-allocated dynamic variables, but their memory is managed automatically.

Thread-local Variables

Thread-local (or thread) variables are used in multithreaded applications. A thread-local variable is like a global variable, except that each thread of execution gets its own private copy of the variable, which cannot be accessed from other threads. Thread-local variables are declared with threadvar instead of var. For example:

 threadvar X: Integer;

Thread-variable declarations:

  • cannot occur within a procedure or function.
  • cannot include initializations.
  • cannot specify the absolute directive.

Dynamic variables that are ordinarily managed by the compiler (long strings, wide strings, dynamic arrays, variants, and interfaces) can be declared with threadvar, but the compiler does not automatically free the heap-allocated memory created by each thread of execution. If you use these data types in thread variables, it is your responsibility to dispose of their memory from within the thread, before the thread terminates. For example:

 threadvar S: AnsiString;
 S := '';  // free the memory used by S
Note: Use of such constructs is discouraged.

You can free a variant by setting it to Unassigned and an interface or dynamic array by setting it to nil.

See Also