delphidelphi-10.2-tokyodelphi-6

Can not assign char array to string in Delphi 10.2


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.


Solution

  • 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);