1

I always pair my initialization of a dynamic array with a finalizer in the form of

finally 
  SetLength(Array, 0); 
end;

It feels more natural to know exactly when the array gets "destroyed" and allows me smoother transition from arrays to TList if needed by already having a "finally" available.

Yet that approach makes the source code more indented. Is there any drawback in this approach - readability, maintainability, extensibility, performance, error prroness?

Sample code I write:

var
  A1: array of Integer;
  A2: array on Boolean;
  A3: array of string;
begin
  SetLength(A1, 10);
  try
    ...
    SetLength(A2, 20);
    try
      ...
      SetLength(A3, 30);
      try
        ...
      finally
        SetLength(A3, 0);
      end;
    finally
      SetLength(A2, 0);
    end;
  finnally
    SetLength(A1, 0);
  end;
end;
Rudy Velthuis
  • 28,387
  • 5
  • 46
  • 94
Gad D Lord
  • 6,620
  • 12
  • 60
  • 106
  • 1
    None of those calls to `SetLength` are necessary, because the variables go out of scope at the final `end;` statement and are automatically released. If the variables were broader in scope (unit wide or global), it might make a difference. You can also remove all of the `try..finally` blocks if that's all they're intended for, which makes the whole indentation question moot. – Ken White Jan 02 '15 at 22:51
  • The amount of indentation is entirely up to you. If you'd like, you could have one procedure with 100 lines of code, or 100 procedures with 1 line of code each. Code indentation doesn't necessarily affect performance. In this case however, you can initialize/uninitialize these arrays together and have only one `try..finally` block, although not recommended. – Jerry Dodge Jan 02 '15 at 22:51
  • @Jerry: Absolutely none of those calls to SetLength or try..finally blocks are needed. – Ken White Jan 02 '15 at 22:53
  • @KenWhite I've faced strange issues in some scenarios if this isn't done, for example, upon terminating the application, I got an exception (don't remember exactly what) which was resolved by setting my array to 0 length. – Jerry Dodge Jan 02 '15 at 22:53
  • @Jerry: Not by code like this, you haven't. Dynamic arrays are reference counted, and it wouldn't matter anyway if your app is closing, as Windows releases all of the memory allocated, If you got an exception, it was for some other reason. – Ken White Jan 02 '15 at 22:56
  • @Ken I found my old question of this scenario, was an older Delphi version with an older memory manager: http://stackoverflow.com/questions/8273473/invalid-pointer-operation-runtime-error-with-custom-drawing – Jerry Dodge Jan 02 '15 at 22:56
  • @Jerry: Read your own **EDIT** at the end of that question, which indicates it was caused by accessing an invalid index to the array. It had nothing to do with SetLength, a memory manager, or anything else but incorrect code. – Ken White Jan 02 '15 at 22:59
  • @Ken Yes, it's a 3 year old question, in which I did not have in front of me to read prior to my initial comment here. My memory isn't that great, I didn't even realize it was a question I asked here at first. – Jerry Dodge Jan 02 '15 at 23:00
  • 2
    I agree with everything Mason said. As a further aside, use `TArray` for dynamic arrays because of more relaxed type compatibility for generics. – David Heffernan Jan 03 '15 at 06:39

1 Answers1

5

Is there any drawback in this approach - readability, maintainability, extensibility, performance, error proneness?

Readability: definitely!

Maintainability, extensibility: As you say, this would make the transition to a TList simpler. But how often do you start off with an array and later convert it to a TList?

Performance: The compiler already does exactly what you're doing. Now it's happening twice. The redundant calls to SetLength when there's nothing to do have minimal overhead, but (in 32-bit at least) those try-finally blocks have some noticeable overhead to them.

Error proneness: Anytime you do something manually that the compiler can handle for you, there's a certain chance you could make a mistake. How often that actually happens is something you would know better than me, but statistically, yes, you increase error proneness by doing this.

Mason Wheeler
  • 82,511
  • 50
  • 270
  • 477
  • 3
    And note that there are implicit try finally blocks around any function body that uses dynarrays, so there are in fact 6 (!!!) nested try finally blocks in the example code. – Rudy Velthuis Jan 03 '15 at 11:10