1

I am wanting to port several large apps from Delphi 2006 to XE. The reasons are not so much to do with Unicode, but to take advantage of (hopefully) better IDE stability, native PNG support, more components, less VCL bugs, less dependence on 3rd party stuff, less ribbing from you guys, etc. Some of the apps might benefit from Unicode, but that's not a concern at present. At the moment I just want to take the most direct route to getting them to compile again.

As a start, I have changed all ambiguous string declarations, i.e. string to AnsiString or ShortString, char to AnsiChar and pChar to pAnsiChar and recompiled with D2006. So far so good. Nothing broke.

My question is: Where to from here? Assuming I just present my sources to the XE compiler and light the touch paper, what is likely to be the big issue?

For example,

var
    S : AnsiString ; 
...
MainForm.Caption := S ;

Will this generate an error? A warning? I'm assuming the VCL is now Unicode, or will XE pull in a non-Unicode component, or convert the string? Is it in fact feasible to keep an app using 8-bit strings in XE, or will there be too many headaches?

If the best/easiest way to go is to Unicode, I'll do that, even though I won't be using the extended characters, at least in the near future anyway.

The other thing that I wonder about is 3rd party stuff. I guess I will need to get updated versions that are XE-compatible.

Any (positive!) comment appreciated.

rossmcm
  • 5,493
  • 10
  • 55
  • 118

2 Answers2

1

It is a long jump taking 2006 to 2011

But it is possible if you consider that:

  • You have to convert String variables using the new conversions methods ;
  • You have to check all the versions between 2006 and xe to know how the libraries have changed, bacause some have been spplited, others merged, and a few deleted ;
  • You have to buy/download the upgrade (if any) of your 3rd party components.
NaN
  • 8,596
  • 20
  • 79
  • 153
0

The VCL is completely Unicode now, so the code you showed will generate a compiler warning, not an error, about an implicit conversion from AnsiString to UnicodeString. That is a potentially lossy conversion if the AnsiString contains non-ASCII characters (which the compiler cannot validate). If you continue using AnsiString, then you have to do an explicit type-cast to avoid the warning:

var
  S : AnsiString ; 
...
MainForm.Caption := String(S);

You are best off NOT Ansi-fying your code like this. Embrace Unicode. Your code will be easier to manage for it, and it will be more portable to future versions and platforms. You should restrict AnsiString usage to just those places where Ansi is actually needed - network communications, file I/O of legacy data, etc. If you want to save memory inside your app, especially if you are using ASCII characters only, use UTF8String instead of AnsiString. UTF-8 is an 8-bit encoding of Unicode, and conversions between UTF8String and UnicodeString are loss-less with no compiler warnings.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thanks @Remy. Going back from `AnsiString` to `String` globally is no big deal (FART is a wonderful tool for that). There is a reasonable amount of code that requires and assumes byte-sized ASCII character strings. If I revert all my declarations to "string", XE will assume UnicodeString. Will it warn me when I code something like `if (S [3] = ':') then...` ? That's the scenario that I don't want to overlook. – rossmcm May 22 '12 at 20:43
  • `':'` is a Character literal. Character literals and String literals are context-sensitive now. When used with a `UnicodeString`, a literal will be Unicode (in the specific case of a `#XX` 2-digit literal in the range of `#80`-`#FF`, its Unicode representation is influenced by the new `HIGHCHARUNICODE` compiler directive). `String`, `Char`, and `PChar` are all Unicode now. If `S` is a `UnicodeString` then you will be comparing a `WideChar` to a `WideChar`. If `S` is as `AnsiString` instead, you will be comparing an `AnsiChar` to an `AnsiChar`. In both cases, no compiler warning is needed. – Remy Lebeau May 22 '12 at 23:01
  • OK. @Remy My point is that, if I have existing code: `var S : string ; begin S := 'hello' ; Writeln (SomeTextFile, S) ;` and the file needs to be 8-bit ASCII and contain the bytes `$68, $65, $6C, $6C, $5F, $0D, $0A` after that code has executed, the XE compiler won't warn me that it's going to treat S as Unicode rather than Asni, and the file contents will be different (and wrong)? Do I understand correctly? – rossmcm May 23 '12 at 12:45
  • No. The old-style Pascal file I/O routines, like `WriteLn()`, do not support Unicode at all. If you pass a `UnicodeString` to `WriteLn()`, it will get converted to Ansi before being written to the file. As long as the `UnicodeString` contains ASCII characters, you will get the output you are expecting. If it contains non-ASCII characters, you may get data loss from the conversion. If you want to support Unicode file I/O, use the VCL's `TStreamWriter` class instead. It has a `WriteLine()` method and supports the `TEncoding` class. – Remy Lebeau May 23 '12 at 21:13