Appending UnicodeString to WideString in Delphi

delphi, unicode-string, widestring

Solution

To answer your question about what the code is actually doing, this statement:

result := result + myUnicodeString;

Does the following:

calls `System._UStrFromWStr()` to convert `Result` to a temp `UnicodeString`

calls `System._UStrCat()` to concatenate `myUnicodeString` onto the temp

calls `System._WStrFromUStr()` to convert the temp to a `WideString` and assign it back to `Result`.

There is a `System._WStrCat()` function for concatenating a `WideString` onto a `WideString` (and `System._UStrCat()` for `UnicodeString`). If CodeGear/Embarcadero had been smarter about it, they could have implemented a `System._WStrCat()` overload that takes a `UnicodeString` as input and a `WideString` as output (and vice versa for concatenating a `WideString` onto a `UnicodeString`). That way, no temp `UnicodeString` conversions would be needed anymore. Both `WideString` and `UnicodeString` are encoded as UTF-16 (well mostly, but I won't get into that here), so concatenating them together is just a matter of a single allocation and move, just like when concatenating two `UnicodeString`s or two `WideString`s together.

Problem

I'm curious about what happens with this piece of code in Delphi 2010: ``` function foo: WideString; var myUnicodeString: UnicodeString; begin for i:=1 to 1000 do begin myUnicodeString := ... something ...; result := result + myUnicodeString; // This is where I'm interested end; end; ``` How many string conversions are involved, and are any particularly bad performance-wise? I know the function should just return a `UnicodeString` instead, but I've seen this anti-pattern in the VCL streaming code, and want to understand the process.

Original source