// *** before: ***
// string meant AnsiString: one byte per character, and the active code
// page decided which letters existed at all
var
S: string; // AnsiString
C: Char; // AnsiChar - exactly one byte
begin
S := 'Hello';
Writeln(Length(S)); // 5 - characters and bytes were the same thing
Writeln(SizeOf(Char)); // 1
C := S[1];
// WideString was the only Unicode string type, and it was a COM BSTR:
// no reference counting, every assignment copied the whole text
end;
// *** in version 2009: ***
// string means UnicodeString: UTF-16, reference counted, copy on write
var
S: string; // UnicodeString
C: Char; // WideChar - two bytes
A: AnsiString; // still here, and it now carries a code page
R: RawByteString; // bytes kept as they are, with no conversion
begin
S := 'Привет';
Writeln(Length(S)); // 6 characters
Writeln(Length(S) * SizeOf(Char)); // 12 bytes - Char is no longer a byte
C := S[1];
A := AnsiString(S); // conversions became explicit
R := RawByteString(A);
// the rule that broke old code: Length counts characters, never bytes,
// so every Move, ReadBuffer and SizeOf calculation had to be revisited
end;