just trying to achieve similar functionality of C/C++ static local variables in ObjectPascal/Delphi. Let's have a following function in C:
bool update_position(int x, int y)
{
static int dx = pow(-1.0, rand() % 2);
static int dy = pow(-1.0, rand() % 2);
if (x+dx < 0 || x+dx > 640)
dx = -dx;
...
move_object(x+dx, y+dy);
...
}
Equivalent ObjectPascal code using typed constants as a static variable replacement fails to compile:
function UpdatePosition(x,y: Integer): Boolean;
const
dx: Integer = Trunc( Power(-1, Random(2)) ); // error E2026
dy: Integer = Trunc( Power(-1, Random(2)) );
begin
if (x+dx < 0) or (x+dx > 640) then
dx := -dx;
...
MoveObject(x+dx, y+dy);
...
end;
[DCC Error] test_f.pas(332): E2026 Constant expression expected
So is there some way for a one-time pass initialized local variable ?
The variable with a static keyword is declared inside a function is known as a static local variable. The scope of the static local variable will be the same as the automatic local variables, but its memory will be available throughout the program execution.
In Java, a static variable is a class variable (for whole class). So if we have static local variable (a variable with scope limited to function), it violates the purpose of static. Hence compiler does not allow static local variable.
Master C and Embedded C Programming- Learn as you go The space for the static variable is allocated only one time and this is used for the entirety of the program. Once this variable is declared, it exists till the program executes. So, the lifetime of a static variable is the lifetime of the program.
A local static variable is a variable, whose lifetime doesn't stop with a function call where it is declared. It extends until the lifetime of a complete program. All function calls share the same copy of local static variables. These variables are used to count the number of times a function is called.
There's no direct equivalent of a C static variable in Delphi.
A writeable typed constant (see user1092187's answer) is almost equivalent. It has the same scoping and instancing properties, but does not allow the one-time initialization that is possible with a C or C++ static variable. In any case it is my opinion that writeable typed constants should be shunned as a quaint historical footnote.
You can use a global variable.
var
dx: Integer;
dy: Integer
function UpdatePosition(x,y: Integer): Boolean;
begin
if (x+dx < 0) or (x+dx > 640) then
dx := -dx;
...
MoveObject(x+dx, y+dy);
...
end;
You have to do the one-time initialization in the initialization
section:
initialization
dx := Trunc( Power(-1, Random(2)) );
dy := Trunc( Power(-1, Random(2)) );
Of course this make a mess of the global namespace unlike the limited scope of a C static variable. In modern Delphi you can wrap it all up in a class and use a combination of class methods, class vars, class constructors to avoid polluting the global namespace.
type
TPosition = class
private class var
dx: Integer;
dy: Integer;
private
class constructor Create;
public
class function UpdatePosition(x,y: Integer): Boolean; static;
end;
class constructor TPosition.Create;
begin
dx := Trunc( Power(-1, Random(2)) );
dy := Trunc( Power(-1, Random(2)) );
end;
class function TPosition.UpdatePosition(x,y: Integer): Boolean;
begin
// your code
end;
Enable "Writable typed constants":
{$J+}
procedure abc;
const
II: Integer = 45;
begin
Inc(II);
ShowMessage(IntToStr(II));
end;
{$J-}
procedure TForm1.Button1Click(Sender: TObject);
begin
abc;
abc;
abc;
end;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With