5

I have the following variable declarations:

arrChar_1: array[0..2] of Char;
arrChar_2: array[0..2] of Char;
str: string;

Then I made the assignment:

str := arrChar_1 + arrChar_2;

This assignment works normally on Delphi 6. But error occurs when I compile it on Delphi 10.2:

[dcc32 Error] MigrateConcatenateCharArray.dpr(26): E2008 Incompatible types

I'm solving this problem in the following way:

str := Copy(first_arrChar, 0, StrLen(first_arrChar));
str := str + Copy(second_arrChar, 0, StrLen(second_arrChar));

Is there any other good solution to this problem? (1)


In Delphi 6:

String = AnsiString
Char = AnsiChar

In Delphi 10.2:

String = UnicodeString
Char = WideChar

Can tell me what caused the incompatibility issue to occur? (2)

I'm understanding that widechar is a multi-byte character type. Unicode is the way that characters are encoded. But I'm confused about them.

  • I would not have expected concatenating arrays to compile in Delphi 6. IF the arrays are null-terminated (which your workaround depends on), you might get away with `str := string(arrChar_1) + string(arrChar_2);` or worst case `str := string(@arrChar_1[0]) + string(@arrChar_2[1]);` But, just for performance reasons, I would probably use `len1 := StrLen(arrChar_1); len2 := StrLen(arrChar_2); SetLength(str, len1 + len2); Move(arrChar_1, PChar(str)^, len1 * sizeof(Char)); Move(arrChar_2, (PChar(str) + len1)^, len2 * sizeof(Char));` or even `str := Format('%s%s', [arrChar_1, arrChar_2]);` – Remy Lebeau Oct 17 '18 at 02:27
  • What about `str := string(arrChar_1) + string(arrChar_2);` ? – Uwe Raabe Oct 17 '18 at 06:25
  • This works: `str := arrChar_1; str := str + arrChar_2;` . It seems to be a compiler error and should be reported at QP. – LU RD Oct 17 '18 at 07:03

1 Answers1

9

The following compiles in all versions of Delphi:

procedure Main;
var
  arrChar_1: array[0..2] of AnsiChar;
  arrChar_2: array[0..2] of AnsiChar;
  str: AnsiString;
begin
  str := arrChar_1 + arrChar_2;
end;

The following code does not compile in Unicode versions of Delphi:

procedure Main;
var
  arrChar_1: array[0..2] of WideChar;
  arrChar_2: array[0..2] of WideChar;
  str: UnicodeString;
begin
  str := arrChar_1 + arrChar_2;
end;

This seems a little odd to me. Why should the concatenation operator be supported for AnsiChar arrays but not WideChar arrays?

If you examine how the concatenation operator is implemented for AnsiChar arrays that begins to shed some light. The generated code first converts the arrays into ShortString instances. These are then converted into Delphi AnsiString instances. Finally the two AnsiString instances are concatenated.

Now, this would explain why the code fails for WideChar arrays. The ShortString type only supports AnsiChar elements and so a different path through the string support routines would have been needed. One can assume that the Embarcadero designers chose, for whatever reason, not to support this form of concatenation when implementing Unicode support.

To back this idea up, consider the following:

procedure Main;
var
  arrChar_1: array[0..254] of AnsiChar;
  arrChar_2: array[0..254] of AnsiChar;
  str: AnsiString;
begin
  str := arrChar_1 + arrChar_2;
end;

This compiles. But change either of the 254 upper bounds to 255 and the code fails to compile (in all versions of Delphi) reporting E2008 Incompatible types. That is because the array now exceeds the maximum length of a ShortString object.

As for how to migrate your code to Unicode Delphi, I suggest that you simply cast the character arrays to string:

str := string(arrChar_1) + string(arrChar_2);
Graymatter
  • 6,319
  • 2
  • 26
  • 47
David Heffernan
  • 572,264
  • 40
  • 974
  • 1,389