Pass a multidimensional array as a parameter (with a hidden caveat)
How to pass a multidimensional array as a parameter? Long ago this question was answered on Stack Overflow with a simple answer: make a specific type for your array. But there is a hidden caveat…
If you need to pass a multidimensional array as a parameter you’d probably type this
1 2 3 |
procedure DoSomething(MyParameter: array of array of Integer); |
however the above code won’t compile (‘E2029 Identifier expected but ARRAY found’). By declaring a specific type for the array it compiles:
1 2 3 4 5 6 |
type TMyArray = array of array of Integer; procedure DoSomething(MyParameter: TMyArray); |
Looks nice, but there is something nasty hidden in there. But let’s take a step back – how about changing your one dimensional array procedures the same way? Your procedure may look like
1 2 3 |
procedure DoSomething(MyParameter: array of Integer); |
but surely is a lot better to read by declaring an integer array type before:
1 2 3 4 5 6 |
type TIntegerArray = array of Integer; procedure DoSomething(MyParameter: TIntegerArray); |
Are both the same? No, they aren’t. Let’s prove it with a little bit of more code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
type TIntegerArray = array of Integer; procedure Inc1(Data: array of Integer); begin Data[0] := Data[0] + 5; end; procedure Inc2(Data: TIntegerArray); begin Data[0] := Data[0] + 5; end; procedure TForm1.Button1Click(Sender: TObject); var Data1: TIntegerArray; begin SetLength(Data1, 1); Data1[0] := 1; Inc1(Data1); Memo1.Lines.Add(Data1[0].toString); Data1[0] := 1; Inc2(Data1); Memo1.Lines.Add(Data1[0].toString); end; |
At first a dynamic array with a size of 1 is created and before the two Inc’s are called it is filled with 1 – as both procedures uses the array passed as a value, both lines should still read “1” afterwards. But the second memo line shows a “6“ – this call is a call by reference!
Adding a const or var doesn’t change anything – the dynamic array is always passed as a reference if declared as a type!
What about the nextgen (iOS/Android) compiler? It’s the same, so be careful by replacing dynamic array parameters by array types – you always end up passing them by reference!
4 Comments to Pass a multidimensional array as a parameter (with a hidden caveat)
These are not “dynamic array parameters”, they are “open array parameters”. You cannot only pass dynamic arrays to them, you can just as well pass static arrays or open array constructors. Do not confuse them with dynamic arrays. More in my article “Open array parameters and array of const”, (http://rvelthuis.de/articles/articles-openarr.html). That also explains why “array of” parameter declarations are not dynamic arrays.
Dynamic arrays are reference types, that is why you can update their values, just like you can change properties if an object is passed into a function.
August 4, 2016
@rudy: You wrote in part “Confusion”:
“procedure OnlyDyn(Arr: TMonthArray) will only accept dynamic arrays, so you can use SetLength here (this will however use a copy, and not change the original array”
But that’s not true – the dynamic array isn’t used a copy – it’s passed as reference (see my example above)!
And yes, I may a bit confused about open and dynamic arrays, thank you for your great article.
…. hmm ok sorry, you wrote “if setlength is used *then* it uses a copy” ..
August 4, 2016
looks like I have to rewrite my article a little bit 😉
August 11, 2016
博客不错,嘎嘎!
Leave a comment
About Dennis D. Spreen
Search
Recent Posts
- How to compile Lua 5.4.0 for Android as a dynamic library using Android Studio 4
- Please make inline vars usable for production – fix RSP-28892
- How to compile Lua 5.4.0 as a Mac OS X dynamic library
- How to compile Lua 5.4.0 for Linux as a shared library
- How to compile Lua 5.4.0 for Windows
- Daily Wage – a Spigot/Bukkit plugin that pays out a daily wage
- How to compile Lua 5.3.5 for Windows
- Better Collada exporter for Blender with custom properties
- MOS6502-delphi – a MOS 6502 CPU emulator for Delphi
- Pass a multidimensional array as a parameter (with a hidden caveat)
Categories
Tags
Archives
- May 2020
- March 2020
- June 2019
- March 2017
- August 2016
- July 2016
- June 2016
- January 2016
- September 2015
- February 2015
- January 2015
- October 2014
- September 2014
- August 2014
- May 2014
- March 2014
- February 2014
- November 2011
- June 2011
- February 2011
- March 2010
- September 2009
- August 2009
- July 2009
- May 2009
- March 2009
- February 2009
- January 2009
- November 2008
- October 2008
- February 2008
- June 2007
Delphi Feeds
- Habari STOMP Client libraries release 2024.12 December 7, 2024
- Delphi and AI December 7, 2024
- Uses Clause Manager topic added to the GExperts help December 6, 2024
- Upgrading C++Builder 12.2: Tip #4 1/2: Check out compiler safety options December 6, 2024
- Upgrading C++Builder 12.2: Tip #4, Take Advantage of Security and Correctness December 5, 2024
- .NET MAUI: Complete Guide December 4, 2024
- Upgrading C++Builder 12.2: Tip #3, Massive Files with iostreams December 4, 2024
- Log exceptions in your Delphi app in the cloud with StellarDS.io December 4, 2024
- Introducing Signotaur - Remote Code Signing Server December 4, 2024
- Upgrading C++Builder 12.2: Tip #2, Handling Old RTL December 3, 2024
August 3, 2016