tags:

views:

370

answers:

2

My understanding is that the static keyword was introduced for compatibility with .NET (along with strict)

class TExample
  class procedure First;
  class procedure Second; static;

The differences between procedures First and Second are :-

  1. First can be overridden in a descendant class
  2. First passes an implicit self parameter referencing the TExample class.

Class procedure Second cannot be overridden and passes no parameters and is thus .NET compatible. So is there any point in using the static keyword in native-only code now that there is a divergence between Delphi & Prism syntax?

+2  A: 

with static, it is a little bit faster. There's one add esp, -8 in method First which is not there in Second.

program staticTest;

{$APPTYPE CONSOLE}

uses
  SysUtils;

type
  TExample=class
    class procedure First;
    class procedure Second; static;
  end;


{ TExample }

class procedure TExample.First;
var
  i : Integer;
begin
  i:=61374;
end;

class procedure TExample.Second;
var
  I : Integer;
begin
  i:=44510;
end;

begin
  { TODO -oUser -cConsole Main : Hier Code einfügen }
  TExample.First;
  TExample.Second;
end.

First:

staticTest.dpr.20: begin
00408474 55               push ebp
00408475 8BEC             mov ebp,esp
00408477 83C4F8           add esp,-$08  ;This is the line I mentioned
0040847A 8945FC           mov [ebp-$04],eax
staticTest.dpr.21: i:=61374;
0040847D C745F8BEEF0000   mov [ebp-$08],$0000efbe
staticTest.dpr.22: end;
00408484 59               pop ecx
00408485 59               pop ecx
00408486 5D               pop ebp
00408487 C3               ret

Second:

staticTest.dpr.27: begin
00408488 55               push ebp
00408489 8BEC             mov ebp,esp
0040848B 51               push ecx
staticTest.dpr.28: i:=44510;
0040848C C745FCDEAD0000   mov [ebp-$04],$0000adde
staticTest.dpr.29: end;
00408493 59               pop ecx
00408494 5D               pop ebp
00408495 C3               ret 
00408496 8BC0             mov eax,eax

In short - I see no reason.

Tobias Langner
The thing is that the first one saves eax. Probably some hardcoded prologue in the compiler. IOW the first apparantly has a parameter and the second not. It might reduce to the same with optimization on though.
Marco van de Voort
+13  A: 

Static class methods have no hidden class reference argument. Because of this, they are assignment compatible with plain old function pointers, and can therefore be used for interaction with the Windows API and other C APIs. Example:

type
  TForm = class
  private
    class function NonStaticWndProc (wnd: HWND; Message: Cardinal;
      wParam: WPARAM; lParam: LPARAM): LRESULT;
    class function StaticWndProc (wnd: HWND; Message: Cardinal;
      wParam: WPARAM; lParam: LPARAM): LRESULT; static;
    procedure RegisterClass;
  end;

procedure TForm.RegisterClass;
type
  TWndProc = function (wnd: HWND; Message: Cardinal;
    wParam: WPARAM; lParam: LPARAM): LRESULT;
var
  WP: TWndProc;
  WindowClass: WNDCLASS;
begin
  //WP := NonStaticWndProc; // doesn't work
  WP := StaticWndProc; // works
  // ...
  TWndProc (WindowClass.lpfnWndProc) := WP;
  Windows.RegisterClass (WindowClass);
end;

(Of course, you could have used a global function instead, but other than global functions, static class functions have a clear association with a class.)

Moritz Beutel