Recent

Author Topic: Zeromemory vs. Fillchar  (Read 2929 times)

Ten_Mile_Hike

  • Full Member
  • ***
  • Posts: 134
Zeromemory vs. Fillchar
« on: July 04, 2025, 12:08:19 am »
Hello Everyone,

  Can anyone tell me why there is a "ZeroMemory(Destination: Pointer; Length: NativeUInt)" operation when we
  already have FillChar(Destination^, Length, 0)? When should I use one over the other, pros and cons etc....
 
  TIA As Always...
When any government, or any church for that matter, undertakes to say to its subjects, This you may not read, this you
must not see, this you are forbidden to know, the end result is tyranny and oppression no matter how holy the motives.

Robert A. Heinlein

dsiders

  • Hero Member
  • *****
  • Posts: 1525
Re: Zeromemory vs. Fillchar
« Reply #1 on: July 04, 2025, 12:13:29 am »
Hello Everyone,

  Can anyone tell me why there is a "ZeroMemory(Destination: Pointer; Length: NativeUInt)" operation when we
  already have FillChar(Destination^, Length, 0)? When should I use one over the other, pros and cons etc....
 
  TIA As Always...

Did you not notice? ZeroMemory is declared only for Windows and that is is implemented as:

Code: [Select]
procedure ZeroMemory(Destination:PVOID; Length:DWORD);
begin
  FillChar(Destination^,Length,#0);
end;

Thaddy

  • Hero Member
  • *****
  • Posts: 18729
  • To Europe: simply sell USA bonds: dollar collapses
Re: Zeromemory vs. Fillchar
« Reply #2 on: July 04, 2025, 07:11:35 am »
Background is simply that ZeroMemory is a Windows API call.
https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/aa366920(v=vs.85)
Since it is a C macro, in FPC it is implemented as a function.
On Windows it is marked legacy and now has as alternative SecureZeroMemory.
In FreePascal we don't need that. because the only reason Microsoft introduced it, is to prevent overaggressive C(++) compilers to simply remove the call to zeromemory altogether.
FPC can't be that aggressive yet  8) ::) It won't skip function calls.
So in FPC SecureZeroMemory would be the exact same as ZeroMemory.
« Last Edit: July 04, 2025, 07:26:57 am by Thaddy »
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

440bx

  • Hero Member
  • *****
  • Posts: 6087
Re: Zeromemory vs. Fillchar
« Reply #3 on: July 04, 2025, 08:06:55 am »
Background is simply that ZeroMemory is a Windows API call.
RtlZeroMemory is a Windows function.  ZeroMemory is a macro.

https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/aa366920(v=vs.85)
As is rather usual, MS doesn't tell the whole story.

RtlZeroMemory is a function implemented in NTDLL, it's (32bit) code is:
Code: ASM  [Select][+][-]
  1. .text:77062890 ; Exported entry 1304. RtlZeroMemory
  2. .text:77062890
  3. .text:77062890 ; =============== S U B R O U T I N E =======================================
  4. .text:77062890
  5. .text:77062890
  6. .text:77062890 ; __stdcall RtlZeroMemory(x, x)
  7. .text:77062890                 public _RtlZeroMemory@8
  8. .text:77062890 _RtlZeroMemory@8 proc near              ; DATA XREF: .text:off_77020210↑o
  9. .text:77062890
  10. .text:77062890 arg_0           = dword ptr  4
  11. .text:77062890 arg_4           = dword ptr  8
  12. .text:77062890
  13. .text:77062890                 push    edi
  14. .text:77062891                 mov     edi, [esp+4+arg_0]
  15. .text:77062895                 mov     ecx, [esp+4+arg_4]
  16. .text:77062899                 xor     eax, eax
  17. .text:7706289B                 cld
  18. .text:7706289C                 mov     edx, ecx
  19. .text:7706289E                 and     edx, 3
  20. .text:770628A1                 shr     ecx, 2
  21. .text:770628A4                 rep stosd
  22. .text:770628A6                 or      ecx, edx
  23. .text:770628A8                 jnz     short loc_770628AE
  24. .text:770628AA                 pop     edi
  25. .text:770628AB                 retn    8
  26. .text:770628AE ; ---------------------------------------------------------------------------
  27. .text:770628AE
  28. .text:770628AE loc_770628AE:                           ; CODE XREF: RtlZeroMemory(x,x)+18↑j
  29. .text:770628AE                 rep stosb
  30. .text:770628B0                 pop     edi
  31. .text:770628B1                 retn    8
  32. .text:770628B1 _RtlZeroMemory@8 endp
  33.  
One nice thing about it is that it tries to minimize the number of moves.


Since it is a C macro, in FPC it is implemented as a function.
It often is a macro that is a synonym of an inline implementation of memset.  BTW, it is definitely not a C macro when programming in Assembler.  In assembler it resolves to the ntdll function.

On Windows it is marked legacy and now has as alternative SecureZeroMemory.
It is questionable that the Secure version is more secure.  In both cases, sizeof is going to be used.  The "security" comes from the occasionally undesirable behavior from the C compiler.  IOW, as genuine functions (not macros), they are both as secure or insecure however you want to look at it.

In FreePascal we don't need that.
It's very useful in FPC, in C and in assembler.

FPC generates inline versions, e.g, character arrays and structures initialized with Default() but Default is simply too inconvenient to be used.

The inline capability is nice but, it can definitely grow the size of the executable (not that anyone who's using the LCL would ever notice.)
 
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

Ten_Mile_Hike

  • Full Member
  • ***
  • Posts: 134
Re: Zeromemory vs. Fillchar
« Reply #4 on: July 04, 2025, 09:45:35 am »
Zeromemory is a wrapper for fillchar... (I should have seen it)
When any government, or any church for that matter, undertakes to say to its subjects, This you may not read, this you
must not see, this you are forbidden to know, the end result is tyranny and oppression no matter how holy the motives.

Robert A. Heinlein

d2010

  • Sr. Member
  • ****
  • Posts: 253
Re: Zeromemory vs. Fillchar
« Reply #5 on: July 09, 2025, 05:37:57 pm »
Hello Everyone,

C:Q1=How to initialize my records  with string? E.g you search ???
   I need initialize with fillchar? Perhaps a combinatioan fillchar and directly zero?
 :-[
Code: Pascal  [Select][+][-]
  1.  
  2. Typ
  3.   NavTree=^TreeRec;
  4.   TreeRec = record
  5.               dxf5:integer;                        //rem:contine adresa curenta a variabile tr
  6.               prefix,midifix,sufix:integer;
  7.               typ: NodeType;
  8.               left, right: NavTree;
  9.               rl: double;
  10.               s:string;tip:_Ttyps;StrL,StrR:word;
  11.               lNode,RNode:NodeType;
  12.               ls,rs:string;???
  13.            end;
  14.  

Code: Pascal  [Select][+][-]
  1. Function makeNode(t: NodeType; l, r: NavTree): NavTree;
  2. begin
  3.     result:=nil;
  4.     New(result); ???
  5. //rem: if (tr<>nil) then fillchar(tr^,ksizeof_treerec,0);
  6. fillchar(tr^,sizeof(tr^)-1,0);
  7. ???
  8.     with result^ do
  9.        begin
  10.          typ := t;
  11.          dxf5:=getmypid[1].lo; //rem:dxf5:=integer(tr);
  12.          rl:=0.0;
  13.          s:='';
  14.          prefix:=0;
  15.          if (length(fmpstr.left)>0) and (pp_vars2scr_setq(prefix,fmpstr.left,nil))
  16.                  then  fmpstr.left:='';
  17.  
  18.          sufix:=0;
  19.          if (length(fmpstr.rigt)>0) and (pp_vars2scr_setq(sufix,fmpstr.rigt,nil))
  20.                  then fmpstr.rigt:='';
  21.  
  22.          midifix:=0;
  23.          if (length(fmpstr.midi)>0)  and (pp_vars2scr_setq(midifix,fmpstr.midi,nil))
  24.                 then  fmpstr.midi:='';
  25.          f113();
  26.          left := l;
  27.          right := r;
  28.     end;
  29. end;
  30.  
  31.   function makeConstNode(T:NodeType;v: double;a:str63;b:_Ttyps): Tree;
  32.   var
  33.     tr: Tree;
  34.   begin
  35.     New(tr);???
  36.         //rem: if (tr<>nil) then fillchar(tr^,ksizeof_treerec,0);
  37.      // I ASK here???
  38.     with tr^ do begin
  39.         typ := T; rl := v;s:=a;tip:=b;
  40.         if s='$C[..]' then Begin strL:=laVal.strL;
  41.                                  strR:=laVal.strR;
  42.                            End;
  43.     end;
  44.     makeConstNode := tr;
  45.   end;
  46.  
  47.  



« Last Edit: July 09, 2025, 05:43:05 pm by d2010 »

Thaddy

  • Hero Member
  • *****
  • Posts: 18729
  • To Europe: simply sell USA bonds: dollar collapses
Re: Zeromemory vs. Fillchar
« Reply #6 on: July 09, 2025, 07:10:23 pm »
Hello Everyone,

C:Q1=How to initialize my records  with string? E.g you search ???
   I need initialize with fillchar? Perhaps a combinatioan fillchar and directly zero?
 :-[
Code: Pascal  [Select][+][-]
  1.  
  2. Typ
  3.   NavTree=^TreeRec;
  4.   TreeRec = record
  5.               dxf5:integer;                        //rem:contine adresa curenta a variabile tr
  6.               prefix,midifix,sufix:integer;
  7.               typ: NodeType;
  8.               left, right: NavTree;
  9.               rl: double;
  10.               s:string;tip:_Ttyps;StrL,StrR:word;
  11.               lNode,RNode:NodeType;
  12.               ls,rs:string;???
  13.            end;
  14.  

Code: Pascal  [Select][+][-]
  1. Function makeNode(t: NodeType; l, r: NavTree): NavTree;
  2. begin
  3.     result:=nil;
  4.     New(result); ???
  5. //rem: if (tr<>nil) then fillchar(tr^,ksizeof_treerec,0);
  6. fillchar(tr^,sizeof(tr^)-1,0);
  7. ???
  8.     with result^ do
  9.        begin
  10.          typ := t;
  11.          dxf5:=getmypid[1].lo; //rem:dxf5:=integer(tr);
  12.          rl:=0.0;
  13.          s:='';
  14.          prefix:=0;
  15.          if (length(fmpstr.left)>0) and (pp_vars2scr_setq(prefix,fmpstr.left,nil))
  16.                  then  fmpstr.left:='';
  17.  
  18.          sufix:=0;
  19.          if (length(fmpstr.rigt)>0) and (pp_vars2scr_setq(sufix,fmpstr.rigt,nil))
  20.                  then fmpstr.rigt:='';
  21.  
  22.          midifix:=0;
  23.          if (length(fmpstr.midi)>0)  and (pp_vars2scr_setq(midifix,fmpstr.midi,nil))
  24.                 then  fmpstr.midi:='';
  25.          f113();
  26.          left := l;
  27.          right := r;
  28.     end;
  29. end;
  30.  
  31.   function makeConstNode(T:NodeType;v: double;a:str63;b:_Ttyps): Tree;
  32.   var
  33.     tr: Tree;
  34.   begin
  35.     New(tr);???
  36.         //rem: if (tr<>nil) then fillchar(tr^,ksizeof_treerec,0);
  37.      // I ASK here???
  38.     with tr^ do begin
  39.         typ := T; rl := v;s:=a;tip:=b;
  40.         if s='$C[..]' then Begin strL:=laVal.strL;
  41.                                  strR:=laVal.strR;
  42.                            End;
  43.     end;
  44.     makeConstNode := tr;
  45.   end;
  46.  
  47.  
Can you make that code generic? So it can fill with bytes, words, integers, qwords etc?  :P 8-) O:-)
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

ASerge

  • Hero Member
  • *****
  • Posts: 2475
Re: Zeromemory vs. Fillchar
« Reply #7 on: July 09, 2025, 08:35:37 pm »
C:Q1=How to initialize my records  with string?
The same. The compiler implicitly initializes all strings in records with a zero (in New call). So FillChar won't make it worse.
Why do you use the value "SizeOf(...) - 1" in FillChar?

Thaddy

  • Hero Member
  • *****
  • Posts: 18729
  • To Europe: simply sell USA bonds: dollar collapses
Re: Zeromemory vs. Fillchar
« Reply #8 on: July 09, 2025, 09:09:22 pm »
Instead of length()?  :(
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

TBMan

  • Sr. Member
  • ****
  • Posts: 347
Re: Zeromemory vs. Fillchar
« Reply #9 on: July 09, 2025, 09:22:44 pm »
I would have used

Code: Pascal  [Select][+][-]
  1. sizeof(TreeRec)
  2.  

If you passed a nil pointer things could get wonky.
Barry

Newest game (clone),
Missile Commander:
https://www.youtube.com/watch?v=tgKz0cxog-k

d2010

  • Sr. Member
  • ****
  • Posts: 253
Re: Zeromemory vs. Fillchar
« Reply #10 on: July 10, 2025, 09:36:14 am »
Instead of length()?  :(

I break my function MakeNode onto theee functions
Code: [Select]
   makeNode_idf("fillchar")
   makeNode_id2(",,,,:=0000 or :='' ");
   makeNode_idz("zeromemory")
I execute boca100=001 and I go\t   the results..All thre function all same results (fillchar isEqualTicks  zeromemory isEqual  d2)
Code: [Select]
.oNow_MakeIdNode.zer="fElapsed",Time="00"
oNow_MakeIdNode.zer="zElapsed",Time="00"
.oNow_MakeIdNode.zer="0Elapsed",Time="00"
But, when I reset boca100=100 at ??? isinside For loop:="; that
100xfillchar is more better that 100xZeroMemory..
100xfillchars got 124
100xZeroMemory got 186;

Other information/s about  "MakeIdNode.zer="0" you found  in attched.zip
Code: [Select]
oBod!t086good..oNow_MakeIdNode.zer="fElapsed",Time="124"
oBod!t086good..oNow_MakeIdNode.zer="zElapsed",Time="186"
oBod!t086good..oNow_MakeIdNode.zer="0Elapsed",Time="79"
The "bigger" is worst, the "small" is more better.
:P
I run my
Code: Pascal  [Select][+][-]
  1. Var boca100=001;???
  2. Function makeNode_id0(rtype: NodeType;lef,rig: NavTree): NavTree;
  3. Var dwg,loop:integer;
  4. Begin dwg:=GetTickCount;
  5.       New(result);
  6.       for loop:=01 to boca100 do
  7.        Case Now_MakeIdNode.zer of
  8. 'f':  makeNode_idf(result,rtype,lef,rig);
  9. '0':  makeNode_id2(result,rtype,lef,rig);
  10. 'z':  makeNode_idz(result,rtype,lef,rig);
  11.       End;
  12.       Now_MakeIdNode.tim:=Now_MakeIdNode.tim+(GetTickCount-dwg);
  13. End;
  14.  
« Last Edit: July 10, 2025, 09:47:55 am by d2010 »

ASerge

  • Hero Member
  • *****
  • Posts: 2475
Re: Zeromemory vs. Fillchar
« Reply #11 on: July 10, 2025, 08:25:18 pm »
But, when I reset boca100=100 at ??? isinside For loop:="; that
100xfillchar is more better that 100xZeroMemory..
100xfillchars got 124
100xZeroMemory got 186;

The functions differ in line 7:
Code: Pascal  [Select][+][-]
  1. Procedure makeNode_idf(Var dest:NavTree;rtype: NodeType; lef, rig: NavTree);
  2. begin
  3.     fillchar(dest^,sizeof(TreeRec),0);
  4.     with dest^ do
  5.        begin
  6.          typ := rtype;
  7.          dxf5:=integer(dest);
  8.          rle:=0.0;
  9. ...
Code: Pascal  [Select][+][-]
  1. Procedure makeNode_idz(Var dest:NavTree;rtype: NodeType; lef, rig: NavTree);
  2. begin
  3.     ZeroMemory(dest,sizeof(TreeRec));
  4.     with dest^ do
  5.        begin
  6.          typ := rtype;
  7.          dxf5:=getmypid[1].lo;
  8.          rle:=0.0;
  9. ...

 

TinyPortal © 2005-2018