Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

True C static local variable replacement?

Tags:

delphi

pascal

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 ?

like image 812
David Unric Avatar asked Dec 11 '11 11:12

David Unric


People also ask

Can a local variable be static in C?

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.

Can we use static for local variable?

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.

What is the lifetime of a static local variable in C?

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.

What is static variable and local variable in C?

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.


2 Answers

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;
like image 162
David Heffernan Avatar answered Sep 28 '22 09:09

David Heffernan


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;
like image 21
user1092187 Avatar answered Sep 28 '22 08:09

user1092187