Variable Expected
Velox reports Variable Expected when a construct needs an addressable, writable storage location but receives a literal, constant, type, routine result or other value expression instead.
Example
A var parameter can modify its caller's storage, so a literal cannot be supplied:
procedure SetPrepared(var Text: string);
begin
Text := 'Prepared';
end;
procedure ScriptEvent(var Value: Variant);
begin
SetPrepared('fixed text'); // Error: Variable Expected
end;
Pass a compatible variable:
procedure SetPrepared(var Text: string);
begin
Text := 'Prepared';
end;
procedure ScriptEvent(var Value: Variant);
var
Text: string;
begin
SetPrepared(Text);
Value := Text;
end;
Current emission families
The modified compiler emits this diagnostic when:
- an actual argument for a
var,outor other non-input parameter is not a variable value; - a string or
Variantelement is assigned through an expression that is not backed by writable storage; - a record field is selected from a temporary value that cannot be addressed as a variable;
- a variable-only identifier lookup finds a type, procedure/function or constant instead;
- a
forstatement supplies something other than a writable counter variable; or - an identifier-led statement resolves to a value expression that is neither an assignment target nor a callable routine.
The check occurs before or alongside type compatibility. A literal passed to a var parameter produces Variable Expected; a real variable of the wrong type proceeds to the stricter check and produces Type mismatch.
Correction procedure
- Identify why the construct needs storage: assignment target, counter,
var/outparameter, address or mutable element/member. - Declare a local variable of the required type.
- Assign any starting value to that variable separately.
- Pass or use the variable in the variable-only position.
- If a function/property returns a record or value, copy it to a local variable, modify the local value, then assign the complete value back through a supported setter when one exists.
- Recompile and resolve any subsequent
Type mismatchseparately.
Edge cases and quirks
- A constant has a value but no writable storage. Renaming a constant does not make it suitable for a
varparameter. - A routine result or calculated expression can be assignment-compatible as an input parameter but still cannot be used as a non-input parameter.
- Properties are implemented through getter/setter calls and do not necessarily have an address. Passing a property as a
varargument can therefore fail even if reading and assigning that property separately are supported. - The formatter ignores the optional name supplied by some emission sites, so the public message is always just
Variable Expected. Use the reported row/column to identify the expression. - A
forcounter must be writable storage and must also have a supported counter type. The two requirements produce different diagnostics. - An assignment to a read-only or read from a write-only registered property produces the more specific property diagnostic.
- This is a compile-time error; the attempted write or call does not occur.
Related reference
Type mismatch- storage exists, but its type is incompatible.Assignment (':=') expected- a writable target was resolved but the assignment token is missing.Read-only property- a property has no registered setter.Write-only property- a property has no registered getter.
External references
- Free Pascal: Variable parameters
- Embarcadero DocWiki: E2036 Variable required
- Embarcadero DocWiki: Declarations and Statements (Delphi)
The Embarcadero E2036 page describes the address-of form of the same storage requirement. Velox uses one broader PascalScript diagnostic for the additional variable-only contexts listed above.