Dynamic array + constant array = incompatible
Dynamic array + constant array = incompatible
I still think this is retarded, particularly with the new array syntax.
function Check(const Extras: array of String): Boolean;
var
List: Array of String;
begin
FillWithDefaults(List);
List := List + Extras; //<-- [dcc32 Error]: E2008 Incompatible types
I still think this is retarded, particularly with the new array syntax.
function Check(const Extras: array of String): Boolean;
var
List: Array of String;
begin
FillWithDefaults(List);
List := List + Extras; //<-- [dcc32 Error]: E2008 Incompatible types
Reading that, my reaction is surely that should work with the new array syntax (as you say.) Isn't this exactly the sort of thing it's meant for?
ReplyDeleteMaybe file a QC report.
That does seem odd. A quick experiment, however, shows that if you declare:
ReplyDeletetype
TStrArray = array of string;
var
MyStrArray: TStrArray;
and this method:
procedure TForm1.AddStrings(const strings: TStrArray);
begin
MyStrArray := MyStrArray + strings;
end;
It builds.
A cent for every time a Delphi developer gets that wrong... (and I admit, its confusing because of the ambiguous syntax)
ReplyDeleteconst array of X as argument type of a routine -> open array
array of X on a variable -> dynamic array
open array incompatible with dynamic array
So:
function Check(const Extras: TArray): Boolean;
var
List: TArray;
begin
FillWithDefaults(List);
List := List + Extras;
...
I think the issue comes from the fact there are two different ways to interpret that code, the classic being an open array parameter, which is NOT compatible with a dynamic array.
ReplyDeleteHaven't tried, but that's my impression at first sight.
Shouldn't the new array syntax understand it anyway? Even if they're different types of arrays, the coder wants to concatenate them. Since the result is a dynamic array that should be doable...?
ReplyDeleteDavid Millington While it would be nice there was never mentioned compatibility of an open array and a dynamic array being part of the new array syntax.
ReplyDeleteStefan Glienke Of course, that requires passing a TArray<>, which you might not have (could be a constant for example).
ReplyDeleteAsbjørn Heid True that. Then you write this:
ReplyDeleteuses
Spring.Collections;
function Check(const Extras: array of string): Boolean;
var
List: TArray;
begin
FillWithDefaults(List);
List := List + TArray.Copy(Extras);
...
However it could be solved by intrinsic compiler support because in this case you first copy the open array to a dynamic array which then gets passed to the concat function to then be thrown away again. Or until that happens you write your own Concat routine that can do that :)
IMO, they should have managed to hide the incompatibility in the new syntax. Element by element, they are compatible, so there should have been compiler magic to take care of it.
ReplyDeleteThat might be right but that would also mean that an open array should be assignment compatible to a dynamic array. Otherwise it would be inconsistent if it only worked for concat.
ReplyDeleteAnd then we can ask the question if it should be copied? Because the original source of the open array can be a dynamic array, a const array or a slice of those.
And what if the original source of the open array was a dynamic array (which just gets passed along with the additional hidden length parameter) should it be copied aswell? But that is inconsistent to how dynamic arrays normally behave for assignments. And with all these things in mind think about Delphi being a strictly typed language that permits many assignments that might be compatible binary wise. You would suddenly implement type assignment compatibility for types that are normally not.
What I would like to see now that we even call the language Object(!!!) Pascal is making TArray a first class citizen of the language with operator overloading and methods like Add, Insert, Delete, IndexOf and so on.
Yes you can fake this right now by making a record wrapping a TArray but then you lose the direct and fast access on the items.
IMO, a copy would be natural - as it is for a string.
ReplyDeleteWhile I agree that assignment should be explicit (localCopy := Copy(paramArray); for example), the Add operator for TArray should work as if the declaration was
ReplyDeleteclass operator Add(const A: TArray; const B: array of T): TArray;
At least I can't see any of the ambiguities that exist when you do a straight assignment.