Author Topic: Is an uninitialized dynamic array's length always zero?  (Read 1178 times)

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12644
  • Debugger - SynEdit - and more
    • wiki
Re: Is an uninitialized dynamic array's length always zero?
« Reply #15 on: July 22, 2026, 11:00:17 pm »
"Result" => that differs from a local var declared in the "var" block of  a routine.

Result (for ansistring / dyn-array) is internally passed as var param. It is a temp var of the caller, and it may have content.

Below compiled with fpc 3.2.3 at -O1 writes numbers from 0 to 10 (tested on Win / 64 bit)

Code: Pascal  [Select][+][-]
  1. program Project1;
  2. type TIntArray = array of integer;
  3.  
  4. function foo: TIntArray;
  5. begin
  6.   writeln(Length(Result));
  7.   SetLength(Result, Length(Result)+1);
  8. end;
  9.  
  10. procedure bar;
  11. var
  12.   i: Integer;
  13.   x: TIntArray;
  14. begin
  15.   for i :=0 to 10 do x := foo;
  16. end;
  17.  
  18. begin
  19.   bar;
  20.   readln;
  21. end.
  22.  

H₂SO₄

  • Sr. Member
  • ****
  • Posts: 487
Re: Is an uninitialized dynamic array's length always zero?
« Reply #16 on: July 23, 2026, 07:08:16 am »
Mind you: Result may have random-ish data in it.

In this case @Martin_fr is (very rare) mistaken: even on stack dynamic arrays are initialized as per my example.

Both are correct: yes, locally-declared dynamic arrays are zeroed on procedure entry, but  Result  (being passed by reference) doesn't actually live in the callee's stack frame and as such isn't automatically zeroed.
Mind you, this way it's still impossible for  Result  to contain truly uninitalized data (since any dynamic array it refers to must've been initialized in its proper frame), but like in @Martin_fr's example nothing prevents the callee from seeing stale (but not uninitialized) data in  Result.

Thaddy

  • Hero Member
  • *****
  • Posts: 19633
  • Glad to be alive.
Re: Is an uninitialized dynamic array's length always zero?
« Reply #17 on: July 23, 2026, 07:17:52 am »
Yes, forgot about result. But internally a dynamic array is initialized.
Any "programmer" that knows only one programming language is not a programmer

bstewart

  • New Member
  • *
  • Posts: 23
Re: Is an uninitialized dynamic array's length always zero?
« Reply #18 on: July 23, 2026, 04:45:09 pm »
So in this specific case:

Code: Pascal  [Select][+][-]
  1. procedure Test();
  2. var
  3.   A: array of byte;
  4. begin
  5.   SetLength(A, 10);
  6. end;

After calling SetLength, the dynamic array A will always contain ten bytes, each of which is zero.

Is this correct?

Thaddy

  • Hero Member
  • *****
  • Posts: 19633
  • Glad to be alive.
Re: Is an uninitialized dynamic array's length always zero?
« Reply #19 on: July 23, 2026, 05:18:03 pm »
Yes!

See the documentation:
https://www.freepascal.org/docs-html/rtl/system/setlength.html

"In case the length is set to a larger length than the current one, the new elements are zeroed out for a dynamic array."

So even if a compiler may complain something about uninitialized, if SetLength is called, in fact, a dynamic array is always initialized.
« Last Edit: July 23, 2026, 06:01:11 pm by Thaddy »
Any "programmer" that knows only one programming language is not a programmer

Warfley

  • Hero Member
  • *****
  • Posts: 2084
Re: Is an uninitialized dynamic array's length always zero?
« Reply #20 on: July 23, 2026, 08:03:44 pm »
Some managed types are not always initialized. E.g. not if they are the result of a function:
Code: Pascal  [Select][+][-]
  1. {$ModeSwitch arrayoperators}
  2. type
  3.   TInts = Array of Integer;
  4. function Test: TInts;
  5. begin
  6.   Result += [0];
  7. end;
  8.  
  9. var
  10.   arr: TInts;
  11. begin
  12.   arr:=Test;
  13.   arr:=Test;
  14.   arr:=Test;
  15.   WriteLn(Length(arr)); // 3
  16. end.

But this is not true for all managed types. Managed records are initialized if they are the result of a function:
Code: Pascal  [Select][+][-]
  1. {$ModeSwitch advancedrecords}
  2. type
  3.   TManaged = record
  4.     x: Integer;
  5.     class operator Initialize(var rec: TManaged);
  6.   end;
  7. class operator TManaged.Initialize(var rec: TManaged);
  8. begin
  9.   rec.x:=0;
  10. end;
  11.  
  12. function Test: TManaged;
  13. begin
  14.   Result.x += 1;
  15. end;
  16.  
  17. var
  18.   r: TManaged;
  19. begin
  20.   r:=Test;
  21.   r:=Test;
  22.   r:=Test;
  23.   WriteLn(r.x); // 1
  24. end.

So long story short, the answer is a firm maybe... It's inconsistent

PascalDragon

  • Hero Member
  • *****
  • Posts: 6422
  • Compiler Developer
Re: Is an uninitialized dynamic array's length always zero?
« Reply #21 on: July 23, 2026, 08:53:16 pm »
Dynamic arrays are "Managed types". They all are initializated automatically.

Why is there a warning about an uninitialized managed type? It is not uninitialized, it is auto-initialized by the compiler. It doesn't make sense to have such a warning, unless it appears only if the array is accessed before any call to SetLength() on it.

I personally would have the warning/hint only for Result and not for local/global variables, but fpk disagrees... 🙄

Thaddy

  • Hero Member
  • *****
  • Posts: 19633
  • Glad to be alive.
Re: Is an uninitialized dynamic array's length always zero?
« Reply #22 on: July 24, 2026, 11:14:21 am »
Some managed types are not always initialized.
True, but not for Setlength() on Dynamic arrays. Which was the question.
Otherwise the docs and the tests are both wrong.(all tests pass)
« Last Edit: July 24, 2026, 11:16:17 am by Thaddy »
Any "programmer" that knows only one programming language is not a programmer

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12644
  • Debugger - SynEdit - and more
    • wiki
Re: Is an uninitialized dynamic array's length always zero?
« Reply #23 on: July 24, 2026, 12:39:18 pm »
Some managed types are not always initialized.
True, but not for Setlength() on Dynamic arrays. Which was the question.
Otherwise the docs and the tests are both wrong.(all tests pass)

The original question
Suppose the following declaration:
Code: Pascal  [Select][+][-]
  1. var
  2.   A: array of byte;
...
Quote
Does an uninitialized dynamic array always have a length of zero, or is this an implementation detail?

1) Does not specify it is a local var, this could be a global, it could even be a field "private var" is possible).  However, if indeed declared with "var" then it is not "result".

2) "an uninitialized" => is somewhat badly worded. Those aren't uninitialized. But for the actual point of the question: Yes those always start with length = zero. (afaik).

So then yes: "result" was not part of the question, but imho should be rightly mentioned as being different, since otherwise you can bet safely that someone will assume it to be part of the answer. And it is not.

Btw, I don't know about "out" param. Maybe, maybe not. No idea.

Thaddy

  • Hero Member
  • *****
  • Posts: 19633
  • Glad to be alive.
Re: Is an uninitialized dynamic array's length always zero?
« Reply #24 on: July 24, 2026, 01:13:03 pm »
Global variables are always initialized. Because heap memory is always initialized.
He wonders if in this particular! case it is <sic> the case.
Any "programmer" that knows only one programming language is not a programmer

bstewart

  • New Member
  • *
  • Posts: 23
Re: Is an uninitialized dynamic array's length always zero?
« Reply #25 on: July 24, 2026, 04:02:49 pm »
Yes!

See the documentation:
https://www.freepascal.org/docs-html/rtl/system/setlength.html

"In case the length is set to a larger length than the current one, the new elements are zeroed out for a dynamic array."

So even if a compiler may complain something about uninitialized, if SetLength is called, in fact, a dynamic array is always initialized.

Right--in fact I quoted that from the doc earlier in this thread.

My question was if that statement is always true, given this code:

Code: Pascal  [Select][+][-]
  1. procedure Test();
  2. var
  3.   A: array of byte;
  4. begin
  5.   SetLength(A, 10);
  6. end;

As you said, the answer is yes. In this specific case--A being a local variable and we are calling SetLength to initialize it--the dynamic array's content will always be initialized to ten zero bytes.

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1604
    • Lebeau Software
Re: Is an uninitialized dynamic array's length always zero?
« Reply #26 on: July 24, 2026, 07:26:28 pm »
Quote
...unless it appears only if the array is accessed before any call to SetLength() on it.

Yes, and in fact that's precisely when it does appear (hence the question).

In that case, I would suggest they re-word the warning to make it clearer what the compiler is actually concerned about. There is a difference between allocating the array in memory, and populating the array with valid data.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

Thaddy

  • Hero Member
  • *****
  • Posts: 19633
  • Glad to be alive.
Re: Is an uninitialized dynamic array's length always zero?
« Reply #27 on: July 26, 2026, 05:20:16 pm »
You can simply do this (uncomment):
Code: Pascal  [Select][+][-]
  1. procedure Test();
  2. var
  3.   A: array of byte;// = nil;// or = (); same thing
  4. begin
  5.   SetLength(A, 10);
  6. end;
  7. begin
  8.  tesl;
  9. end.

But <snippet>:
Code: ASM  [Select][+][-]
  1. # Var A located at rbp-8, size=OS_64
  2. .Ll6:
  3.         movq    $0,-8(%rbp) # <------ the variable is initialized to nil by the compiler.
  4. .Lj11:
  5.         nop
  6. .Lj7:
  7. .Ll7:
  8. # [7] SetLength(A, 10);

No worries. Any stack issues are prevented by that code.
I haven't looked at Delphi, but in FPC it is totally safe.
« Last Edit: July 26, 2026, 05:24:24 pm by Thaddy »
Any "programmer" that knows only one programming language is not a programmer

PascalDragon

  • Hero Member
  • *****
  • Posts: 6422
  • Compiler Developer
Re: Is an uninitialized dynamic array's length always zero?
« Reply #28 on: July 27, 2026, 10:05:32 pm »
Because heap memory is always initialized.

To be pedantic, they aren't on the heap in that sense (meaning some memory that is allocated using GetMem or similar), instead its part of the .bss section mapped in as zero initialized virtual memory during loading of the binary.

Thaddy

  • Hero Member
  • *****
  • Posts: 19633
  • Glad to be alive.
Re: Is an uninitialized dynamic array's length always zero?
« Reply #29 on: July 28, 2026, 03:12:30 pm »
That is not pedantic, that is showing me something new and I could have seen that.
Anyway, it is initialized as the assembler shows.
Any "programmer" that knows only one programming language is not a programmer

 

TinyPortal © 2005-2018