Delphi pass array by reference
Asked Answered
Q

2

6

In C++ is possible to pass to a function a vector by const reference in this way:

void test(const std::vector<int>& a);

This is useful when the vector is very big and I want to avoid the waste of time of making copy of it. I know that the same code in Delphi is:

procedure test(const [Ref] a: array of Integer);

Does it also have the same effect as C++ (pass the address instead of a copy and optimize/save time)? Is this the only way or there is also something else to optimize the parameter passing?

Qualm answered 15/12, 2016 at 8:51 Comment(12)
You are confusing open array parameters and dynamic arrays. There is no need for the [Ref] here. Open array parameters are passed as two parameters. The first one contains the address of the first element of the array. The second one the length of the array (numer of elements) minus one, the so called High() value.Peroneus
Delphi dynamic arrays are always reference-types. But you should use dynamic arrays, not open arrays (it is a legacy-derived mess here, I admit). For example procedure test(const a: TArray<integer>);Kuhl
@Arioch'The That prevents you from passing statically allocated arrays, or using open array constructors. It forces you into heap allocation where none is needed. Open array parameters are not legacy, they are mainstream, well designed, and very useful. They should be used where possible to make your code as composable as possible.Toehold
I don't see how static arrays are anything like std::vector. Come one, you even suggested using TList instead - how about statically allocated TList instances ???Kuhl
@Arioch'The I did not suggest anything at all, read my answer more carefully please. I attempted to present facts. Looking purely at Delphi code, open arrays parameters are more flexible than dynamic parameters, certainly for input. That is inarguable fact. The only point where open array parameters fall down is if you wish the callee to modify the length of the array. In all other circumstances there are advantages to using open array parameters.Toehold
Well, what about "code is written for humans to read rather than for compilers to parse"? Open arrays arr source of confusion and ambiguity and they only matter when using generally obsolete static arrays. IOW they are but a niche feature for those feeling experienced enough to leave general ways and optimize code by using niche features.Kuhl
@Arioch'The They really aren't that hard to understand. And I don't even see any evidence that Raffaele is confused about open array parameters. Rudy seems to have jumped to that conclusion so far as I can tell. Static arrays are absolutely not obsolete. Many things are well modelled by static arrays. The ability to have automatically allocated variables of value types is very valuable in many ways. I strongly reject your assertion that all arrays should be heap allocated dynamic arrays.Toehold
One should not introduce new entities until required. Occam. Static arrays require new entities as their explicit boundaries, and they would be either magic constants (which would tend to crawl into all the algorithms working with that array) or at best named consts (tending to pollute namespace and human attention span). Dynamic arrays with Low/High functions and array constructors can do almost all what static arrays can do, so the latter become niche tools. For parsing binary fixed formats, for example.Kuhl
Granted, there still is one purpose that dynarrays cannot do - and that is using non-integer types for indexing. Using enumerator-types for example. Good niche. But AFAIR it has no analogue from C++ where one can not have a static array over enum-type. So, this niche (good one per se) is void in the context of this question.Kuhl
"evidence that Raffaele is confused about open array parameters" - no evidence, but quite a hint. He puts two quotes - a C++ code and a Pascal code. He brings them as his best effort to code the same concept in C++ and Pascal. As two reflections of the same idea. That hints that he sees a generic dynamic array std::vector<int>& a and open array array of Integer being the same concept in the context, expressed by means of different languages. That is not the EVIDENCE that he thinks his Pascal quotation features a dynamic array, it is not. But quite a hint.Kuhl
@Arioch Utter piffle. Static arrays for fixed size numeric vectors with value semantics are a primary mainstream use case.Toehold
Agreed. One who got bored with type T3DPoint = record X,Y,Z: double end; can well use type T3DPoint = array[1..3] of double; instead. I remember i did it. So, shame for me for overlooking this perfectly valid niche. Still the rule of thumb holds, when one can validate choice of niche tools (like the opt-in criteria you listed: if vector and if fixed size vector and if fixed size that never would change vector and if never-change fixed length vector passed by value) then he has a valid reason to start using them.Kuhl
T
14
procedure test(const a: array of Integer);

This is an open array, passed as const. These are already passed by reference. Adding [ref] in this situation is needless.

Only if you pass an open array by value will a copy will be made:

procedure test(a: array of Integer);

The other option, for sake of completeness, is to pass by var.

procedure test(var a: array of Integer);

Here the array is passed by reference, but, in contrast to the const array, the compiler permits its content to be modified.


I know that the same code in Delphi is ...

That's not quite accurate. Probably the best mapping from C++ std::vector<T> is to Delphi's TList<T>. Probably the closest match to a Delphi open array parameter would be a C++ array parameter. You might map your Delphi procedure:

procedure test(const a: array of Integer);

to this C++ function:

void test(const int a[], const size_t len);

So you aren't really comparing like for like.

That said, Delphi dynamic arrays, which you might well be using when you actually call such a function, are managed types. This means that their lifetimes are managed by automatic reference counting (ARC) and that sets them apart from raw C++ arrays.

I'm rambling somewhat now. Mostly what I am trying to get at is that the devil is in the details. None of these things map perfectly between these languages because the languages have their subtle differences.

But, leaving these nuances aside, if you wish to pass an array efficiently in Delphi, then a const open array will achieve that.

Toehold answered 15/12, 2016 at 9:45 Comment(0)
P
8

You are confusing open array parameters and dynamic arrays. There is no need for the [Ref] here.

Open array parameters are actually passed as two parameters.

  • The first one contains the address of the first element of the array.
  • The second one the length of the array (number of elements) minus one, the so called High() value.

A vector in C++ is a class. It is passed like a class in Delphi, but constness is different. In Delphi, even if you pass a class as const, its methods can still be called. And in Delphi, class instances are references already. No need for the [Ref].

More info on open array parameters in my article.

Peroneus answered 15/12, 2016 at 9:5 Comment(6)
In the C++ code, you can call methods on the vector instance, but only the const methods.Toehold
Ok but if I passed an open array as const [Ref] does it make sense? Or they are passed by ref by default?Qualm
@Rudy I don't see any evidence of confusion with dynamic arrays. The question does not mention dynamic arrays.Toehold
@RaffaeleRossi technically, open arrays are TWO values rather than one. And they are not the initial source some-array-kind variable but rather a result of implicit types-casting function over those docwiki.embarcadero.com/RADStudio/Berlin/en/Open_ArraysKuhl
@David: He mentions std::vector, which is more or less the C++ (class) equivalent of a dynamic array (or, actually, of a TList<T>). FWIW, I didn't say that in C++, you could call methods other than const. But in Delphi, you can.Peroneus
Have a nice journey, Rudy. You have always been a beacon of light for Delphi programmers!Hagai

© 2022 - 2024 — McMap. All rights reserved.