<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: A rant concerning Unicode and Delphi</title>
	<atom:link href="http://blog.delphi-jedi.net/2008/05/10/a-rant-concerning-unicode-and-delphi/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.delphi-jedi.net/2008/05/10/a-rant-concerning-unicode-and-delphi/</link>
	<description>Joint Endeavor of Delphi Innovators of Windows Programming</description>
	<lastBuildDate>Wed, 10 Mar 2010 10:20:45 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=abc</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Prophet</title>
		<link>http://blog.delphi-jedi.net/2008/05/10/a-rant-concerning-unicode-and-delphi/comment-page-1/#comment-2997</link>
		<dc:creator>Prophet</dc:creator>
		<pubDate>Thu, 07 Aug 2008 07:40:08 +0000</pubDate>
		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=177#comment-2997</guid>
		<description>God. I love reading posts where coders argue and stress over things that most people dont care about, dont know about and would not understand even if it was explained in detail. 

I dont claim to understand all that is said. Infact, learned a thing or two from all this.

Lovely stuff.</description>
		<content:encoded><![CDATA[<p>God. I love reading posts where coders argue and stress over things that most people dont care about, dont know about and would not understand even if it was explained in detail. </p>
<p>I dont claim to understand all that is said. Infact, learned a thing or two from all this.</p>
<p>Lovely stuff.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Oliver</title>
		<link>http://blog.delphi-jedi.net/2008/05/10/a-rant-concerning-unicode-and-delphi/comment-page-1/#comment-643</link>
		<dc:creator>Oliver</dc:creator>
		<pubDate>Mon, 12 May 2008 18:38:18 +0000</pubDate>
		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=177#comment-643</guid>
		<description>&lt;blockquote&gt;How come you complain that “PChar(somestring) + 1″ silently breaks if “somestring” is not really a string but an offset,&lt;/blockquote&gt;It&#039;s a pointer. The 1 is the offset. It seems, from your statement (&quot;is not really a string&quot;), that your experiences with pointers are very limited.

&lt;blockquote&gt;but at the same time you suggest using “someapifunction(@bla[1])” which breaks silently, too?&lt;/blockquote&gt;Yes I do. Oh wait, so you blame &lt;em&gt;me&lt;/em&gt; for the fact that CodeGear&#039;s &quot;compiler magic&quot; breaks the the well-famed strict type checking? Hehe, &lt;em&gt;that&#039;s&lt;/em&gt; funny. :lol: ... yeah, shoot the messenger. Still a popular theme.

&lt;blockquote&gt;Are you sure that it is impossible to find an example that would silently break if PChar was changed to PAnsiChar?&lt;/blockquote&gt;Yes. 100% sure for Win32 development (i.e. ignoring Kylix, which I haven&#039;t ever tried). Because there was simply only one meaning for &lt;code&gt;PAnsiChar&lt;/code&gt; and &lt;code&gt;PChar&lt;/code&gt; and both &lt;em&gt;were&lt;/em&gt; equal.

&lt;blockquote&gt;How come you think it would be better to break thousands of lines of code just in order to avoid breaking a corner case problem?&lt;/blockquote&gt;Declaring pointer arithmetics a corner case is a ridiculous statement at best. Apart from that, how big are the projects you&#039;re working on? I had to smirk, when I read over your sentence the first time ... now I am left to frown.

&lt;blockquote&gt;Apart from that there is an easy workaround: Do a global search and replace from PChar to PAnsiChar.&lt;/blockquote&gt;Sure ... which will break &lt;em&gt;exactly because&lt;/em&gt; of the change in Tiburon.</description>
		<content:encoded><![CDATA[<blockquote><p>How come you complain that “PChar(somestring) + 1″ silently breaks if “somestring” is not really a string but an offset,</p></blockquote>
<p>It&#8217;s a pointer. The 1 is the offset. It seems, from your statement (&#8221;is not really a string&#8221;), that your experiences with pointers are very limited.</p>
<blockquote><p>but at the same time you suggest using “someapifunction(@bla[1])” which breaks silently, too?</p></blockquote>
<p>Yes I do. Oh wait, so you blame <em>me</em> for the fact that CodeGear&#8217;s &#8220;compiler magic&#8221; breaks the the well-famed strict type checking? Hehe, <em>that&#8217;s</em> funny. <img src='http://blog.delphi-jedi.net/wp-includes/images/smilies/icon_lol.gif' alt=':lol:' class='wp-smiley' />  &#8230; yeah, shoot the messenger. Still a popular theme.</p>
<blockquote><p>Are you sure that it is impossible to find an example that would silently break if PChar was changed to PAnsiChar?</p></blockquote>
<p>Yes. 100% sure for Win32 development (i.e. ignoring Kylix, which I haven&#8217;t ever tried). Because there was simply only one meaning for <code>PAnsiChar</code> and <code>PChar</code> and both <em>were</em> equal.</p>
<blockquote><p>How come you think it would be better to break thousands of lines of code just in order to avoid breaking a corner case problem?</p></blockquote>
<p>Declaring pointer arithmetics a corner case is a ridiculous statement at best. Apart from that, how big are the projects you&#8217;re working on? I had to smirk, when I read over your sentence the first time &#8230; now I am left to frown.</p>
<blockquote><p>Apart from that there is an easy workaround: Do a global search and replace from PChar to PAnsiChar.</p></blockquote>
<p>Sure &#8230; which will break <em>exactly because</em> of the change in Tiburon.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Sebastian</title>
		<link>http://blog.delphi-jedi.net/2008/05/10/a-rant-concerning-unicode-and-delphi/comment-page-1/#comment-642</link>
		<dc:creator>Sebastian</dc:creator>
		<pubDate>Mon, 12 May 2008 18:16:13 +0000</pubDate>
		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=177#comment-642</guid>
		<description>How come you complain that &quot;PChar(somestring) + 1&quot; silently breaks if &quot;somestring&quot; is not really a string but an offset, but at the same time you suggest using &quot;someapifunction(@bla[1])&quot; which breaks silently, too?

Are you sure that it is impossible to find an example that would silently break if PChar was changed to PAnsiChar?

How come you think it would be better to break thousands of lines of code just in order to avoid breaking a corner case problem? Apart from that there is an easy workaround: Do a global search and replace from PChar to PAnsiChar.</description>
		<content:encoded><![CDATA[<p>How come you complain that &#8220;PChar(somestring) + 1&#8243; silently breaks if &#8220;somestring&#8221; is not really a string but an offset, but at the same time you suggest using &#8220;someapifunction(@bla[1])&#8221; which breaks silently, too?</p>
<p>Are you sure that it is impossible to find an example that would silently break if PChar was changed to PAnsiChar?</p>
<p>How come you think it would be better to break thousands of lines of code just in order to avoid breaking a corner case problem? Apart from that there is an easy workaround: Do a global search and replace from PChar to PAnsiChar.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Oliver</title>
		<link>http://blog.delphi-jedi.net/2008/05/10/a-rant-concerning-unicode-and-delphi/comment-page-1/#comment-641</link>
		<dc:creator>Oliver</dc:creator>
		<pubDate>Mon, 12 May 2008 14:37:06 +0000</pubDate>
		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=177#comment-641</guid>
		<description>&lt;blockquote&gt;What conclusion do you think am I going to draw from this?&lt;/blockquote&gt;Oh, is this becoming a quiz now? :mrgreen: ... my guess is, that you aren&#039;t satisfied with the type checking in the &quot;Delphi language&quot; after your test and that you will migrate to a language that provides stricter type checking. Am I right? :mrgreen:

The error is the third call to &lt;code&gt;GetProcAddress&lt;/code&gt;, because &lt;code&gt;GetProcAddress&lt;/code&gt; doesn&#039;t take a wide character string for the function name. The second call gives a warning (and rightly so, because it has the same result as the first call). The first call doesn&#039;t give a warning. Read further to find out why.

So thanks for making my point about the strictness of type checking in Delphi versus C++! ;)

To show you how I look at things most of the time, a little trip into a binary (console) which contains the first two calls as given by you:

&lt;pre&gt;mov     eax, ds:S
call    WStrToPWChar    ; System::WStrToPWChar(System::WideString)
push    eax
push    ebx             ; Pass module handle
call    GetProcAddress
mov     eax, ds:S       ; Direct &quot;conversion&quot; to Pointer
push    eax
push    ebx             ; Pass module handle
call    GetProcAddress&lt;/pre&gt;
Comments (except the first) are from me. I also shortened the lines, after copying them from IDA, for the sake of brevity. So what conclusion do you draw from this little excerpt of assembly? Let me give you mine:
&lt;ol&gt;&lt;li&gt;Delphi hid the fact that the first and the second call are exactly the same from us, because &quot;compiler magic&quot; (of which string handling is a good part) isn&#039;t part of the actual language and therefore the necessary type check doesn&#039;t take place. If you think the typed address compiler switch (&lt;code&gt;{$T+}&lt;/code&gt;) would change a thing, think again.&lt;/li&gt;
&lt;li&gt;The Delphi type checking is inferior to the one of C++. Unless, of course, you are an especially &quot;smart&quot; C-programmer writing all casts in C++ as C-casts. Been there, fixed their code.&lt;/li&gt;&lt;/ol&gt;

My guess is, what you were trying to say is, that &lt;code&gt;@S[1]&lt;/code&gt; is worse than &lt;code&gt;PCharType(S)&lt;/code&gt;. So I take it you&#039;re considering &lt;code&gt;@S[1]&lt;/code&gt;, which is perfectly valid code, as wrong or so and there should be a different treatment involving intransparent compiler magic? Or maybe your point was to show that you can make the compiler shut up despite formally wrong code (passing wide character string to ANSI-only function)? Please, unless you own your copy of the professional versions of IDA, download &lt;a href=&quot;http://www.datarescue.com/idabase/freefiles/idafree49.exe&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;IDA Standard Free 4.9&lt;/a&gt; and look a bit under the hood for yourself.

Let me give you an example in return which doesn&#039;t involve pointer arithmetics. Before Tiburon (&lt;code&gt;System.pas&lt;/code&gt;), Delphi 2006, to be exact:
&lt;pre style=&quot;border:1px solid #808080; padding: 2pt;&quot;&gt;  PVarRec = ^TVarRec;
  TVarRec = record { ... }
    case Byte of
      vtInteger:    (VInteger: Integer; VType: Byte);
      vtBoolean:    (VBoolean: Boolean);
      vtChar:       (VChar: Char);
      vtExtended:   (VExtended: PExtended);
      vtString:     (VString: PShortString);
      vtPointer:    (VPointer: Pointer);
      vtPChar:      (VPChar: &lt;span style=&quot;color:red&quot;;&gt;PChar&lt;/span&gt;);
      vtObject:     (VObject: TObject);
      vtClass:      (VClass: TClass);
      vtWideChar:   (VWideChar: WideChar);
      vtPWideChar:  (VPWideChar: PWideChar);
      vtAnsiString: (VAnsiString: Pointer);
      vtCurrency:   (VCurrency: PCurrency);
      vtVariant:    (VVariant: PVariant);
      vtInterface:  (VInterface: Pointer);
      vtWideString: (VWideString: Pointer);
      vtInt64:      (VInt64: PInt64);
  end;&lt;/pre&gt;
Uh oh. So I guess since &lt;code&gt;PChar&lt;/code&gt; was never intended to be only ANSI. I am the only misguided Delphi-developer in the whole wide world in that I didn&#039;t get that &lt;code&gt;PChar&lt;/code&gt; was meant to be a &quot;conditional type&quot;. So the red &lt;code&gt;PChar&lt;/code&gt; above will implicitly mean &lt;code&gt;PWideChar&lt;/code&gt; with Tiburon and CodeGear will introduce a new variant sub-type &lt;code&gt;vtPAnsiChar&lt;/code&gt; for &lt;code&gt;PAnsiChar&lt;/code&gt;?! Or maybe the implementer of that part of &lt;code&gt;System.pas&lt;/code&gt; made exactly the same wrong assumption as a big part of the Delphi community and will get bitten by it?! I&#039;d really love to get a sneak-peek into this piece of code in a beta of Tiburon ...

But the &lt;em&gt;really&lt;/em&gt; interesting part will be structures with dynamic offsets where, the implementer chose &lt;code&gt;PChar&lt;/code&gt; to do his pointer arithmetics, because before Tiburon, only some types allowed the implicit pointer arithmetic (without &lt;code&gt;Inc&lt;/code&gt; and &lt;code&gt;Dec&lt;/code&gt;), as pointed out in Allen&#039;s post. Try &lt;code&gt;PByte&lt;/code&gt;, for example, which would be the logical substitute - doesn&#039;t even work in Delphi 2006, although I was of the impression they had fixed that before. Apparently not.

I am not complaining about the parts where the compiler complains - they can and will be fixed, because they are visible through the compiler warnings. Of course you can always make the compiler shut up, but if you do so deliberately, bear the consequences! What I am complaining about is the fact that CodeGear wasn&#039;t clear about the fact that &lt;code&gt;PChar&lt;/code&gt; is (and always was) meant as a &quot;conditional type&quot; and that CodeGear/Borland themselves were using &lt;code&gt;PChar&lt;/code&gt; in contexts were it was clearly ANSI-only. This, in combination with advanced use of Delphi is an explosive mix.

Here&#039;s an example:
&lt;pre style=&quot;border:1px solid #808080; padding: 2pt;&quot;&gt;program UTest;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Windows;

{$DEFINE MIMICTIBURON}

{$IFDEF MIMICTIBURON}
type XString = System.WideString;
type XPChar = System.PWideChar;
{$ELSE}
type XString = System.AnsiString;
type XPChar = System.PAnsiChar;
{$ENDIF}

type
  PMyRecord = ^TMyRecord;
  TMyRecord = record
    SomethingElse : LongWord;
    OffsetToString : LongWord;
  end;

const
  hex_offsets : array[0..$F] of Byte =
    (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8);

var
  x : array[0..$1000-1] of Byte;
  ppmr : PMyRecord;
  pac : XPChar;
  i : Integer;
begin
{$IFDEF MIMICTIBURON}
  Writeln(&#039;Mimicry of Tiburon with old code&#039;);
{$ELSE}
  Writeln(&#039;Old code on old Delphi&#039;);
{$ENDIF}
  ppmr := PMyRecord(@x);
  // Fill buffer ...
  for i := Low(x) to High(x)-1 do
  begin
    x[i] := Ord(&#039;0&#039;) + (i mod 16) + hex_offsets[(i mod 16)];
  end;
  // Zero terminate the &quot;string&quot;
  x[477] := 0;
  // Prepare offset
  ppmr^.OffsetToString := 411;
  Writeln(&#039;Record address   : &#039;, Format(&#039;%p&#039;, [ppmr]));
  Writeln(&#039;Offset to string : &#039;, ppmr^.OffsetToString);
  pac := XPChar(ppmr) + ppmr^.OffsetToString;
  Writeln(&#039;Address of string: &#039;, Format(&#039;%p&#039;, [Pointer(pac)]));
end.&lt;/pre&gt;

And here&#039;s the output with and without MIMICTIBURON defined:
&lt;pre&gt;Old code on old Delphi
Record address   : 0040E220
Offset to string : 411
Address of string: 0040E3BB

Mimicry of Tiburon with old code
Record address   : 0040E220
Offset to string : 411
Address of string: 0040E556&lt;/pre&gt;

Please note, that &lt;strong&gt;neither one&lt;/strong&gt; of the two builds &lt;strong&gt;gave a warning&lt;/strong&gt;!

Fun-fact at the end. Had CodeGear introduced the subscript operator and implicit pointer arithmetic before Tiburon, things wouldn&#039;t be as bad either, because people would not have resorted to &lt;code&gt;PChar&lt;/code&gt; for offset calculations, but rather to &lt;code&gt;PWhateverType&lt;/code&gt;. Now they introduce both, break the logic, but don&#039;t break the code. This means they break it &lt;em&gt;half-heartedly&lt;/em&gt;.</description>
		<content:encoded><![CDATA[<blockquote><p>What conclusion do you think am I going to draw from this?</p></blockquote>
<p>Oh, is this becoming a quiz now? <img src='http://blog.delphi-jedi.net/wp-includes/images/smilies/icon_mrgreen.gif' alt=':mrgreen:' class='wp-smiley' />  &#8230; my guess is, that you aren&#8217;t satisfied with the type checking in the &#8220;Delphi language&#8221; after your test and that you will migrate to a language that provides stricter type checking. Am I right? <img src='http://blog.delphi-jedi.net/wp-includes/images/smilies/icon_mrgreen.gif' alt=':mrgreen:' class='wp-smiley' /> </p>
<p>The error is the third call to <code>GetProcAddress</code>, because <code>GetProcAddress</code> doesn&#8217;t take a wide character string for the function name. The second call gives a warning (and rightly so, because it has the same result as the first call). The first call doesn&#8217;t give a warning. Read further to find out why.</p>
<p>So thanks for making my point about the strictness of type checking in Delphi versus C++! <img src='http://blog.delphi-jedi.net/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>To show you how I look at things most of the time, a little trip into a binary (console) which contains the first two calls as given by you:</p>
<p><pre><pre>mov&nbsp;&nbsp;&nbsp;&nbsp; eax, ds:S
call&nbsp;&nbsp;&nbsp;&nbsp;WStrToPWChar&nbsp;&nbsp;&nbsp;&nbsp;; System::WStrToPWChar(System::WideString)
push&nbsp;&nbsp;&nbsp;&nbsp;eax
push&nbsp;&nbsp;&nbsp;&nbsp;ebx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Pass module handle
call&nbsp;&nbsp;&nbsp;&nbsp;GetProcAddress
mov&nbsp;&nbsp;&nbsp;&nbsp; eax, ds:S&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Direct &quot;conversion&quot; to Pointer
push&nbsp;&nbsp;&nbsp;&nbsp;eax
push&nbsp;&nbsp;&nbsp;&nbsp;ebx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Pass module handle
call&nbsp;&nbsp;&nbsp;&nbsp;GetProcAddress</pre></pre><br />
Comments (except the first) are from me. I also shortened the lines, after copying them from IDA, for the sake of brevity. So what conclusion do you draw from this little excerpt of assembly? Let me give you mine:</p>
<ol>
<li>Delphi hid the fact that the first and the second call are exactly the same from us, because &#8220;compiler magic&#8221; (of which string handling is a good part) isn&#8217;t part of the actual language and therefore the necessary type check doesn&#8217;t take place. If you think the typed address compiler switch (<code>{$T+}</code>) would change a thing, think again.</li>
<li>The Delphi type checking is inferior to the one of C++. Unless, of course, you are an especially &#8220;smart&#8221; C-programmer writing all casts in C++ as C-casts. Been there, fixed their code.</li>
</ol>
<p>My guess is, what you were trying to say is, that <code>@S[1]</code> is worse than <code>PCharType(S)</code>. So I take it you&#8217;re considering <code>@S[1]</code>, which is perfectly valid code, as wrong or so and there should be a different treatment involving intransparent compiler magic? Or maybe your point was to show that you can make the compiler shut up despite formally wrong code (passing wide character string to ANSI-only function)? Please, unless you own your copy of the professional versions of IDA, download <a href="http://www.datarescue.com/idabase/freefiles/idafree49.exe" target="_blank" rel="nofollow">IDA Standard Free 4.9</a> and look a bit under the hood for yourself.</p>
<p>Let me give you an example in return which doesn&#8217;t involve pointer arithmetics. Before Tiburon (<code>System.pas</code>), Delphi 2006, to be exact:<br />
<pre><pre style="border:1px solid #808080; padding: 2pt;">&nbsp;&nbsp;PVarRec = ^TVarRec;
&nbsp;&nbsp;TVarRec = record { ... }
&nbsp;&nbsp;&nbsp;&nbsp;case Byte of
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vtInteger:&nbsp;&nbsp;&nbsp;&nbsp;(VInteger: Integer; VType: Byte);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vtBoolean:&nbsp;&nbsp;&nbsp;&nbsp;(VBoolean: Boolean);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vtChar:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (VChar: Char);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vtExtended:&nbsp;&nbsp; (VExtended: PExtended);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vtString:&nbsp;&nbsp;&nbsp;&nbsp; (VString: PShortString);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vtPointer:&nbsp;&nbsp;&nbsp;&nbsp;(VPointer: Pointer);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vtPChar:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(VPChar: &lt;span style=&quot;color:red&quot;;&gt;PChar&lt;/span&gt;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vtObject:&nbsp;&nbsp;&nbsp;&nbsp; (VObject: TObject);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vtClass:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(VClass: TClass);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vtWideChar:&nbsp;&nbsp; (VWideChar: WideChar);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vtPWideChar:&nbsp;&nbsp;(VPWideChar: PWideChar);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vtAnsiString: (VAnsiString: Pointer);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vtCurrency:&nbsp;&nbsp; (VCurrency: PCurrency);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vtVariant:&nbsp;&nbsp;&nbsp;&nbsp;(VVariant: PVariant);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vtInterface:&nbsp;&nbsp;(VInterface: Pointer);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vtWideString: (VWideString: Pointer);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vtInt64:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(VInt64: PInt64);
&nbsp;&nbsp;end;</pre></pre><br />
Uh oh. So I guess since <code>PChar</code> was never intended to be only ANSI. I am the only misguided Delphi-developer in the whole wide world in that I didn&#8217;t get that <code>PChar</code> was meant to be a &#8220;conditional type&#8221;. So the red <code>PChar</code> above will implicitly mean <code>PWideChar</code> with Tiburon and CodeGear will introduce a new variant sub-type <code>vtPAnsiChar</code> for <code>PAnsiChar</code>?! Or maybe the implementer of that part of <code>System.pas</code> made exactly the same wrong assumption as a big part of the Delphi community and will get bitten by it?! I&#8217;d really love to get a sneak-peek into this piece of code in a beta of Tiburon &#8230;</p>
<p>But the <em>really</em> interesting part will be structures with dynamic offsets where, the implementer chose <code>PChar</code> to do his pointer arithmetics, because before Tiburon, only some types allowed the implicit pointer arithmetic (without <code>Inc</code> and <code>Dec</code>), as pointed out in Allen&#8217;s post. Try <code>PByte</code>, for example, which would be the logical substitute &#8211; doesn&#8217;t even work in Delphi 2006, although I was of the impression they had fixed that before. Apparently not.</p>
<p>I am not complaining about the parts where the compiler complains &#8211; they can and will be fixed, because they are visible through the compiler warnings. Of course you can always make the compiler shut up, but if you do so deliberately, bear the consequences! What I am complaining about is the fact that CodeGear wasn&#8217;t clear about the fact that <code>PChar</code> is (and always was) meant as a &#8220;conditional type&#8221; and that CodeGear/Borland themselves were using <code>PChar</code> in contexts were it was clearly ANSI-only. This, in combination with advanced use of Delphi is an explosive mix.</p>
<p>Here&#8217;s an example:<br />
<pre><pre style="border:1px solid #808080; padding: 2pt;">program UTest;

{$APPTYPE CONSOLE}

uses
&nbsp;&nbsp;SysUtils,
&nbsp;&nbsp;Windows;

{$DEFINE MIMICTIBURON}

{$IFDEF MIMICTIBURON}
type XString = System.WideString;
type XPChar = System.PWideChar;
{$ELSE}
type XString = System.AnsiString;
type XPChar = System.PAnsiChar;
{$ENDIF}

type
&nbsp;&nbsp;PMyRecord = ^TMyRecord;
&nbsp;&nbsp;TMyRecord = record
&nbsp;&nbsp;&nbsp;&nbsp;SomethingElse : LongWord;
&nbsp;&nbsp;&nbsp;&nbsp;OffsetToString : LongWord;
&nbsp;&nbsp;end;

const
&nbsp;&nbsp;hex_offsets : array[0..$F] of Byte =
&nbsp;&nbsp;&nbsp;&nbsp;(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8);

var
&nbsp;&nbsp;x : array[0..$1000-1] of Byte;
&nbsp;&nbsp;ppmr : PMyRecord;
&nbsp;&nbsp;pac : XPChar;
&nbsp;&nbsp;i : Integer;
begin
{$IFDEF MIMICTIBURON}
&nbsp;&nbsp;Writeln(&#039;Mimicry of Tiburon with old code&#039;);
{$ELSE}
&nbsp;&nbsp;Writeln(&#039;Old code on old Delphi&#039;);
{$ENDIF}
&nbsp;&nbsp;ppmr := PMyRecord(@x);
&nbsp;&nbsp;// Fill buffer ...
&nbsp;&nbsp;for i := Low(x) to High(x)-1 do
&nbsp;&nbsp;begin
&nbsp;&nbsp;&nbsp;&nbsp;x[i] := Ord(&#039;0&#039;) + (i mod 16) + hex_offsets[(i mod 16)];
&nbsp;&nbsp;end;
&nbsp;&nbsp;// Zero terminate the &quot;string&quot;
&nbsp;&nbsp;x[477] := 0;
&nbsp;&nbsp;// Prepare offset
&nbsp;&nbsp;ppmr^.OffsetToString := 411;
&nbsp;&nbsp;Writeln(&#039;Record address&nbsp;&nbsp; : &#039;, Format(&#039;%p&#039;, [ppmr]));
&nbsp;&nbsp;Writeln(&#039;Offset to string : &#039;, ppmr^.OffsetToString);
&nbsp;&nbsp;pac := XPChar(ppmr) + ppmr^.OffsetToString;
&nbsp;&nbsp;Writeln(&#039;Address of string: &#039;, Format(&#039;%p&#039;, [Pointer(pac)]));
end.</pre></pre></p>
<p>And here&#8217;s the output with and without MIMICTIBURON defined:<br />
<pre><pre>Old code on old Delphi
Record address&nbsp;&nbsp; : 0040E220
Offset to string : 411
Address of string: 0040E3BB

Mimicry of Tiburon with old code
Record address&nbsp;&nbsp; : 0040E220
Offset to string : 411
Address of string: 0040E556</pre></pre></p>
<p>Please note, that <strong>neither one</strong> of the two builds <strong>gave a warning</strong>!</p>
<p>Fun-fact at the end. Had CodeGear introduced the subscript operator and implicit pointer arithmetic before Tiburon, things wouldn&#8217;t be as bad either, because people would not have resorted to <code>PChar</code> for offset calculations, but rather to <code>PWhateverType</code>. Now they introduce both, break the logic, but don&#8217;t break the code. This means they break it <em>half-heartedly</em>.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Sebastian</title>
		<link>http://blog.delphi-jedi.net/2008/05/10/a-rant-concerning-unicode-and-delphi/comment-page-1/#comment-637</link>
		<dc:creator>Sebastian</dc:creator>
		<pubDate>Mon, 12 May 2008 08:50:30 +0000</pubDate>
		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=177#comment-637</guid>
		<description>@Oliver:

If you have the following code, which call to GetProcAddress will show a compiler warning, which call will show a compiler error?
&lt;code&gt;
// Delphi 2006
var
  S: WideString;
begin
  GetProcAddress(FHandle, @S[1]);
  GetProcAddress(FHandle, PAnsiChar(S));
  GetProcAddress(FHandle, PWideChar(S));
end;
&lt;/code&gt;

What conclusion do you think am I going to draw from this?</description>
		<content:encoded><![CDATA[<p>@Oliver:</p>
<p>If you have the following code, which call to GetProcAddress will show a compiler warning, which call will show a compiler error?<br />
<pre><code>
// Delphi 2006
var
&nbsp;&nbsp;S: WideString;
begin
&nbsp;&nbsp;GetProcAddress(FHandle, @S[1]);
&nbsp;&nbsp;GetProcAddress(FHandle, PAnsiChar(S));
&nbsp;&nbsp;GetProcAddress(FHandle, PWideChar(S));
end;
</code></pre></p>
<p>What conclusion do you think am I going to draw from this?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Christian Wimmer</title>
		<link>http://blog.delphi-jedi.net/2008/05/10/a-rant-concerning-unicode-and-delphi/comment-page-1/#comment-633</link>
		<dc:creator>Christian Wimmer</dc:creator>
		<pubDate>Sun, 11 May 2008 23:47:34 +0000</pubDate>
		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=177#comment-633</guid>
		<description>JWSCL users don&#039;t have this problem. JWSCL converts the strings depending on the UNICODE directive.</description>
		<content:encoded><![CDATA[<p>JWSCL users don&#8217;t have this problem. JWSCL converts the strings depending on the UNICODE directive.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Oliver</title>
		<link>http://blog.delphi-jedi.net/2008/05/10/a-rant-concerning-unicode-and-delphi/comment-page-1/#comment-632</link>
		<dc:creator>Oliver</dc:creator>
		<pubDate>Sun, 11 May 2008 23:08:36 +0000</pubDate>
		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=177#comment-632</guid>
		<description>By the way: I&#039;ve always advocated using:
&lt;pre&gt;var bla: String;
begin
  // do stuff ...
  someapifunction(@bla[1]);
  // do more stuff ...
end;&lt;/pre&gt;... adding the explicit cast to &lt;code&gt;PChar&lt;/code&gt; as you do will, in the worst case, shut up the compiler and do the wrong thing.</description>
		<content:encoded><![CDATA[<p>By the way: I&#8217;ve always advocated using:<br />
<pre><pre>var bla: String;
begin
&nbsp;&nbsp;// do stuff ...
&nbsp;&nbsp;someapifunction(@bla[1]);
&nbsp;&nbsp;// do more stuff ...
end;</pre></pre>&#8230; adding the explicit cast to <code>PChar</code> as you do will, in the worst case, shut up the compiler and do the wrong thing.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Oliver</title>
		<link>http://blog.delphi-jedi.net/2008/05/10/a-rant-concerning-unicode-and-delphi/comment-page-1/#comment-631</link>
		<dc:creator>Oliver</dc:creator>
		<pubDate>Sun, 11 May 2008 23:05:32 +0000</pubDate>
		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=177#comment-631</guid>
		<description>Very good example. If you have this code in your project(s) you&#039;re already in trouble. You write:

&lt;pre&gt;GetProcAddress(FHandle, PChar(name));&lt;/pre&gt;

Now, &lt;code&gt;GetProcAddress&lt;/code&gt; is a function that has no Unicode equivalent because the exported function names are always ANSI, actually ASCII (i.e. characters up to ordinal value 127), if I recall correctly.

&lt;blockquote&gt;You existing API calls work.&lt;/blockquote&gt;Nope, it won&#039;t. You just proved my point, by giving a practical example as it is used out there ;)</description>
		<content:encoded><![CDATA[<p>Very good example. If you have this code in your project(s) you&#8217;re already in trouble. You write:</p>
<p><pre>GetProcAddress(FHandle, PChar(name));</pre></p>
<p>Now, <code>GetProcAddress</code> is a function that has no Unicode equivalent because the exported function names are always ANSI, actually ASCII (i.e. characters up to ordinal value 127), if I recall correctly.</p>
<blockquote><p>You existing API calls work.</p></blockquote>
<p>Nope, it won&#8217;t. You just proved my point, by giving a practical example as it is used out there <img src='http://blog.delphi-jedi.net/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jaakko</title>
		<link>http://blog.delphi-jedi.net/2008/05/10/a-rant-concerning-unicode-and-delphi/comment-page-1/#comment-629</link>
		<dc:creator>Jaakko</dc:creator>
		<pubDate>Sun, 11 May 2008 22:37:21 +0000</pubDate>
		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=177#comment-629</guid>
		<description>I understand your point but keeping PChar to PAnsiChar won&#039;t generate many problems. Let me give a sample. If PChar would still be PAnsiChar it would break huge amount of code that calls to WIN32 API. Now if you pass a string to API you normally cast it to PChar

GetProcAddress(FHandle, PChar(name));

Now name is string and ultimately AnsiString. When using Unicode name is also string but WideString. I guess when using Unicode the W version WIN32 API is used so it requires PWideChar instead of PAnsiChar.

There is no conversion from WideString to PAnsiChar but compiler must generate error. This is solved then PChar is PWideChar. You existing API calls work.</description>
		<content:encoded><![CDATA[<p>I understand your point but keeping PChar to PAnsiChar won&#8217;t generate many problems. Let me give a sample. If PChar would still be PAnsiChar it would break huge amount of code that calls to WIN32 API. Now if you pass a string to API you normally cast it to PChar</p>
<p>GetProcAddress(FHandle, PChar(name));</p>
<p>Now name is string and ultimately AnsiString. When using Unicode name is also string but WideString. I guess when using Unicode the W version WIN32 API is used so it requires PWideChar instead of PAnsiChar.</p>
<p>There is no conversion from WideString to PAnsiChar but compiler must generate error. This is solved then PChar is PWideChar. You existing API calls work.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Oliver</title>
		<link>http://blog.delphi-jedi.net/2008/05/10/a-rant-concerning-unicode-and-delphi/comment-page-1/#comment-623</link>
		<dc:creator>Oliver</dc:creator>
		<pubDate>Sun, 11 May 2008 16:26:46 +0000</pubDate>
		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=177#comment-623</guid>
		<description>&lt;blockquote&gt;Why is it a windows convention? Because it is written in C. Is it really a windows convention then or just a bit of language detail bleeding out the edges of the win api?&lt;/blockquote&gt;Maybe you want to read my post and my replies to the comments again?! There is neither a C nor a C++ (standard) type of the name &lt;code&gt;PCHAR&lt;/code&gt; it&#039;s a type declared in the Windows SDK. The Windows SDK, formerly Platform SDK (PSDK) is &lt;em&gt;the&lt;/em&gt; reference for the Windows platform, whether you like it or not. And whether you like it or not, it was the template for the Delphi units declaring the Win32 functions. I understand that if you never used anything beyond Delphi, the whole thing becomes a mashup, because you get the &quot;contents of the SDK&quot; (at the time of product release) in the Delphi installation directory. It doesn&#039;t change the fact, that the SDK is the reference, though and that Delphi as a Windows development tool should stick to its conventions as far as possible.

Maybe it is a coincidence with the overlap of the name, maybe not. Who knows? Is it important? Nope. What&#039;s important are the problems arising from it. And I&#039;ve gone into enough detail about those.

BTW: I did not even claim no one has ever used &lt;code&gt;PCHAR&lt;/code&gt; outside of the Windows context and so on. That was you putting words in my mouth.

&lt;blockquote&gt;Explain to me again, why you think a pascal lanuage has to adhere to non pascal language standards?&lt;/blockquote&gt;Sorry, don&#039;t like to repeat myself over and over again ;)

Look, I am completely indifferent about the tools I use for development, I use the tool the suits my needs best, although people here seem to think just because I point out a shortcoming of (current and former) Delphi versions and because &lt;em&gt;I&lt;/em&gt; am opposed to the way this transition to the Unicode-ability is handled, I am an enemy of Delphi. Whatever, keep thinking it. If it wasn&#039;t for critics, how would those products ever evolve, if everyone says: &quot;Oh, product XYZ is sooo nice, it&#039;s perfect, I love it ... unconditionally&quot;.</description>
		<content:encoded><![CDATA[<blockquote><p>Why is it a windows convention? Because it is written in C. Is it really a windows convention then or just a bit of language detail bleeding out the edges of the win api?</p></blockquote>
<p>Maybe you want to read my post and my replies to the comments again?! There is neither a C nor a C++ (standard) type of the name <code>PCHAR</code> it&#8217;s a type declared in the Windows SDK. The Windows SDK, formerly Platform SDK (PSDK) is <em>the</em> reference for the Windows platform, whether you like it or not. And whether you like it or not, it was the template for the Delphi units declaring the Win32 functions. I understand that if you never used anything beyond Delphi, the whole thing becomes a mashup, because you get the &#8220;contents of the SDK&#8221; (at the time of product release) in the Delphi installation directory. It doesn&#8217;t change the fact, that the SDK is the reference, though and that Delphi as a Windows development tool should stick to its conventions as far as possible.</p>
<p>Maybe it is a coincidence with the overlap of the name, maybe not. Who knows? Is it important? Nope. What&#8217;s important are the problems arising from it. And I&#8217;ve gone into enough detail about those.</p>
<p>BTW: I did not even claim no one has ever used <code>PCHAR</code> outside of the Windows context and so on. That was you putting words in my mouth.</p>
<blockquote><p>Explain to me again, why you think a pascal lanuage has to adhere to non pascal language standards?</p></blockquote>
<p>Sorry, don&#8217;t like to repeat myself over and over again <img src='http://blog.delphi-jedi.net/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Look, I am completely indifferent about the tools I use for development, I use the tool the suits my needs best, although people here seem to think just because I point out a shortcoming of (current and former) Delphi versions and because <em>I</em> am opposed to the way this transition to the Unicode-ability is handled, I am an enemy of Delphi. Whatever, keep thinking it. If it wasn&#8217;t for critics, how would those products ever evolve, if everyone says: &#8220;Oh, product XYZ is sooo nice, it&#8217;s perfect, I love it &#8230; unconditionally&#8221;.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
