{"id":426,"date":"2009-04-28T09:22:29","date_gmt":"2009-04-27T21:22:29","guid":{"rendered":"https:\/\/www.deltics.co.nz\/blog\/?p=426"},"modified":"2009-04-28T10:19:14","modified_gmt":"2009-04-27T22:19:14","slug":"the-big-switch","status":"publish","type":"post","link":"https:\/\/www.deltics.co.nz\/blog\/posts\/426\/","title":{"rendered":"The &#8220;Big Switch&#8221;"},"content":{"rendered":"<span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">[Estimated Reading Time: <\/span> <span class=\"rt-time\">4<\/span> <span class=\"rt-label rt-postfix\">minutes]<\/span><\/span><p>Much has been made in the past and again more recently, about the lack of a compiler switch in Delph 2009 to govern the behaviour of the String type.<\/p>\n<p>CodeGear have repeatedly said that it was not possible\/practical to provide such a switch, but their advice to anyone concerned about a unilateral change from ANSI to Unicode string in their applications itself suggests that a switch was not only possible, but actually very simple to incorporate.\u00a0 So much so that they could provide it even now without having to change anything already delivered in Delphi 2009 or committed to for Delphi 2010.<\/p>\n<p>Let me explain what I mean.<\/p>\n<p><!--more--><\/p>\n<h2>It&#8217;s Just Not Possible<\/h2>\n<p>When asserting that it is impossible to provide a switch to govern String type, there has I think been an assumption that it was expected that this switch would also affect the VCL and RTL.\u00a0 Hands are thrown in the air and there is much wailing and gnashing of teeth about the impracticalities of providing two versions of the VCL and RTL &#8211; one ANSI and one Unicode.<\/p>\n<p>But I believe that most developers are happy or at least willing to accept that the VCL and RTL should make\/have made the transition to Unicode &#8211; it is their own <span style=\"text-decoration: underline;\">application<\/span> code that is of concern.\u00a0 Even for those who might ideally prefer a switchable or dual-VCL etc, a situation where application code can be more easily migrated whilst preserving ANSI&#8217;ness where needed is likely to be more palatable than the current &#8220;Unicode or Bust&#8221; predicament that they find themselves in.<\/p>\n<p>But in respect of application code (by which I mean code that is not provided as part of the VCL\/RTL, so this would also encompass 3rd party component code for which you have the source), the standard advice for anyone concerned that String variables becoming UnicodeString in Delphi 2009 is this:<\/p>\n<blockquote><p>Find all declarations of String and Char and related types in your code, and change them to ANSIString and ANSIChar etc.<\/p><\/blockquote>\n<p>Although the source for the VCL is provided with Delphi, making modifications &#8211; directly &#8211; to that source is not always straightforward and of course not officially supported and future releases of the VCL source will make no attempt to accommodate &#8220;local&#8221; revisions to VCL source.<\/p>\n<p>So in general, whilst it may be possible it is not &#8220;a good idea&#8221; and in any case, changing the formal types of string type variables cannot &#8211; practically &#8211; extend to the VCL or the RTL units.<\/p>\n<h2>The Long (Hand) and Short (Hand) Of It<\/h2>\n<p>We can conceptually wind the clock back, to the time of the introduction of LongString in Delphi.\u00a0 At that time a switch <span style=\"text-decoration: underline;\">was<\/span> provided and the VCL\/RTL worked with either Short or Long String types. \u00a0But let us instead imagine that the same arguments w.r.t &#8220;Dual VCL&#8217;s&#8221; had applied to LongString and that the VCL\/RTL had unilaterally &#8220;gone LongString&#8221;.<\/p>\n<p>If the VCL\/RTL were declared to be exclusively &#8220;LongString&#8221; capable, then each unit in the VCL\/RTL would simply have needed a compiler directive to override any project settings:<\/p>\n<pre class=\"delphi\">{$H+}<\/pre>\n<p>or alternatively (and more clearly)<\/p>\n<pre class=\"delphi\">{$LONGSTRINGS ON}<\/pre>\n<p>In individual applications, the lack of any specific directive in a unit would allow the project specific setting of this compiler switch to prevail, but the embedding of the directive in the VCL\/RTL units would ensure that those would remain &#8220;LongString&#8221;.<\/p>\n<p>It seems to me that the same approach could be extended quite simple to the String type differences introduced by the transition to Unicode:<\/p>\n<pre class=\"delphi\">{$STRINGTYPE UNICODE}  \/\/ String = UnicodeString, Char = WideChar etc\r\n{$STRINGTYPE ANSI}     \/\/ String = ANSIString, Char = ANSIChar etc<\/pre>\n<p>The absence of a $STRINGTYPE directive would of course allow the project setting to apply.\u00a0 In VCL\/RTL units the directive would be present to ensure UNICODE support in the VCL\/RTL as currently assumed in the Delphi 2009 source.\u00a0 The current assumption would simply be made explicit.<\/p>\n<p><em><strong>NOTE: <\/strong>The existing $LONGSTRINGS directive would have an affect only when $STRINGTYPE is ANSI.<\/em><\/p>\n<p>In otherwords, a $STRINGTYPE directive would provide a way to do in a single line (in a quickly and easily reversible fashion) exactly what CodeGear currently recommend is done in a more laborious and more difficult to reverse fashion &#8211; i.e. manually changing the types of string declarations in application code.<\/p>\n<h2>A Small, Specific Example<\/h2>\n<p>In one project I am involved in, the FastStrings unit is used extensively throughout the application (reflecting the fact that the application has a long and illustrious history).<\/p>\n<p>The FastStrings unit simply does not compile in Delphi 2009 due to the use of &#8220;String&#8221; and &#8220;Char&#8221; declarations and some invalid assumptions about element sizes in some inline assembler code that result when compiled with those types reflecting UnicodeString and WideChar and not the ANSI types (which FastStrings assumes).<\/p>\n<p>The solution &#8211; currently &#8211; is to go through the FastStrings unit replacing &#8220;String&#8221; with &#8220;ANSIString&#8221;, &#8220;Char&#8221; with &#8220;ANSIChar&#8221; etc.<\/p>\n<p>If a $STRINGTYPE directive were available, the <span style=\"text-decoration: underline;\">exact same result<\/span> could be achieved by simply adding:<\/p>\n<pre class=\"delphi\">{$STRINGTYPE ANSI}<\/pre>\n<p>At the top of that unit.\u00a0 This unit would then compile exactly as it did in previous versions of Delphi and it&#8217;s programming interface to the &#8220;outside world&#8221; (other code) would reflect it&#8217;s ANSI specific nature, just as it would had the declarations all been laboriously and manually modified.<\/p>\n<p>In the meantime, the VCL would continue to be Unicode, the RTL would continue to be Unicode and application code using the FastStrings unit would continue to use whatever String type was applicable in each case.<\/p>\n<p>Even without such a directive added to the top of the FastStrings unit itself, if an application were compiled in Delphi 2009 with it&#8217;s project settings configured with STRINGTYPE = ANSI, it too would compile with FastStrings, but again the VCL and RTL would remain resolutely Unicode.<\/p>\n<p>It is important to remember of course that suitable warnings\/errors would still be presented if ANSI application code were found to cause difficulties where string data is passed between application code and the VCL\/RTL, but this situation again is <span style=\"text-decoration: underline;\">exactly the same<\/span> as if that application code had been manually modified to an entirely and explicitly ANSI base.<\/p>\n<p>The difference is, you could quickly check either across an entire application or in an individual unit, what the final outcome would be of compiling for ANSI\/UNICODE, without having to go to so much trouble.<\/p>\n<p><em><strong>NOTE:<\/strong> As my investigation into string performance in Delphi 2009 last year revealed, much of the benefit of the FastStrings library appears to be superceded in Delphi 2009, but not all.\u00a0 It&#8217;s use here is to provide an example of how a compiler switch would assist in easily and safely migrating even extremely &#8220;String sensitive&#8221; code, <span style=\"text-decoration: underline;\">not<\/span> to provide a concrete example of where the use of such a switch would necessarily be the optimal strategy in any one particular case.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p><span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">[Estimated Reading Time: <\/span> <span class=\"rt-time\">4<\/span> <span class=\"rt-label rt-postfix\">minutes]<\/span><\/span> Much has been made in the past and again more recently, about the lack of a compiler switch in Delph 2009 to govern the behaviour of the String type. CodeGear have repeatedly said that it was not possible\/practical to provide such a switch, but their advice to anyone concerned about a unilateral change from ANSI [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":[]},"categories":[4],"tags":[71,292,22],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p1TKYv-6S","jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":563,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/563\/","url_meta":{"origin":426,"position":0},"title":"Delphi Unicode = Wide-ANSI","date":"26 Sep 2009","format":false,"excerpt":"Be careful what you wish for. A lot of people were overjoyed to hear that Unicode support was coming to Delphi. Some were skeptical of the chosen implementation approach however, it all seemed just a little bit too easy. I was one, and sadly it seems I was right. I've\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":349,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/349\/","url_meta":{"origin":426,"position":1},"title":"Delphi 2009 &#8211; String Performance","date":"18 Sep 2008","format":false,"excerpt":"NOTE: Downloads are now fixed! Andreas Hausladen generously took the time to make some detailed comments on my previous post, one of which prompted me to throw together some further performance test cases for String types specifically.\u00a0 The results were something of a mixed bag and contained some surprises. The\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/delphi2009-stringperformance-resultscapture.jpg?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":338,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/338\/","url_meta":{"origin":426,"position":2},"title":"Delphi 2009 &#8211; A Heads-Up for Low-Level Coders","date":"13 Sep 2008","format":false,"excerpt":"Prompted by a conversation with some colleagues where-in we collectively speculated about the implementation details of a generic class and what impact - if any - this might have on performance vs a \"traditional\" polymorphic equivalent, I threw together a quick performance test case in my Smoketest framework, and as\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1240,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/1240\/","url_meta":{"origin":426,"position":3},"title":"What&#8217;s in a Word &#8230; ?","date":"21 Sep 2012","format":false,"excerpt":"In an exchange with David Heffernan both on SO and in the comments here on Te Waka, I had cause to climb in my own personal \"Wayback Machine\" and further investigate an apparent change in compiler behaviour between Delphi 2007 and 2009. This change was first identified as the result\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2006,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/2006\/","url_meta":{"origin":426,"position":4},"title":"Blowing Smoke&#8230;","date":"01 Nov 2013","format":false,"excerpt":"To alleviate the grind of polishing and sanitising my code (and, let's be honest, just plain 'fixing' it in some cases) ready for release, I have re-kindled my participation on Stack Overflow. In a happy confluence yesterday a question came up which allowed me to exercise one of the libraries\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"Ready to Run","src":"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-09.00.33.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":375,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/375\/","url_meta":{"origin":426,"position":5},"title":"Delphi 2009 &#8211; StringPerformance Redux","date":"22 Sep 2008","format":false,"excerpt":"It looks like I may have jumped the gun with my conclusions from the previous exercise to benchmark string performance in Delphi 2009.\u00a0 Following a useful exchange in the comments with Kryvich I corrected a small discrepancy in the tests and made some changes to the performance testing subsystem within\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/delphi2009-stringperformance-chart.jpg?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/426"}],"collection":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/comments?post=426"}],"version-history":[{"count":7,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/426\/revisions"}],"predecessor-version":[{"id":433,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/426\/revisions\/433"}],"wp:attachment":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/media?parent=426"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/categories?post=426"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/tags?post=426"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}