{"id":2605,"date":"2017-03-21T07:56:35","date_gmt":"2017-03-20T19:56:35","guid":{"rendered":"https:\/\/www.deltics.co.nz\/blog\/?p=2605"},"modified":"2017-03-21T07:56:35","modified_gmt":"2017-03-20T19:56:35","slug":"the-varying-and-variant-value-of-true","status":"publish","type":"post","link":"https:\/\/www.deltics.co.nz\/blog\/posts\/2605\/","title":{"rendered":"The Varying (and Variant) Value of True"},"content":{"rendered":"<span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">[Estimated Reading Time: <\/span> <span class=\"rt-time\">&lt; 1<\/span> <span class=\"rt-label rt-postfix\">minutes]<\/span><\/span><p>My most recent posts have prompted a bit of discussion, and it seems some concern, regarding the implementation of Boolean values in Delphi.  The concern at least I think is unwarranted, as long as you avoid explicitly comparing a Boolean value to the <strong>True<\/strong> constant and allow the compiler to logically evaluate the Boolean itself.  But in <a href=\"https:\/\/www.deltics.co.nz\/blog\/posts\/2597\/comment-page-1#comment-16377\">the follow up investigations of one commenter (thank you Arthur)<\/a>, a further occurrence of the alternate <strong>-1<\/strong> identity of <strong>True<\/strong> has been identified: <strong>Variants<\/strong>.<\/p>\n<p><!--more--><\/p>\n<p>Arthur posted the following demonstration that passing a Boolean <strong>True<\/strong> through an intermediate <strong>Variant<\/strong> variable would transmute the Delphi <strong>True<\/strong> with ordinality <strong>1<\/strong> into an integer with ordinality <strong>-1<\/strong>:<\/p>\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\r\nprocedure TForm1.Button1Click(Sender: TObject);\r\nvar aVariant:Variant; \r\n      b:boolean; \r\n      i:integer;\r\nbegin\r\n  b:=True;\r\n\r\n  i:=integer(b); \/\/Cast Bool to Int\r\n  Showmessage(format('In Delphi, TRUE is %d',[i]));\r\n\r\n  aVariant:=b; \/\/ boolean -&gt; variant\r\n  i:=aVariant; \/\/ variant -&gt; Int\r\n\r\n  Showmessage(format('True is now suddenly %d',[i]));\r\nend;\r\n<\/pre>\n<p>The thing to remember about <strong>Variant<\/strong> is that it was born in COM at a time when VB was the dominant language in that space.  As Raymond Chen explains, <a href=\"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/20041222-00\/?p=36923\">it was the VB\/BASIC definition of Boolean that largely determined the COM <strong>Variant<\/strong> implementation<\/a>.  So a <em>Variant<\/em> Boolean with the value <strong>True<\/strong> has the ordinal value <strong>VARIANT_TRUE<\/strong>.<\/p>\n<p>Or <strong>-1<\/strong>.<\/p>\n<p>Of course, this isn&#8217;t actually an explanation of why <strong>-1<\/strong> was chosen in BASIC, only why the BASIC definition was subsequently adopted in COM\/Variant.  The underlying rationale for the use of <strong>-1<\/strong> at all is I think is most readily explained by the bit-flipping, logical negation of <strong>0<\/strong>.<\/p>\n<p>And as is also apparent from Raymond&#8217;s post, the apparent schizophrenia of <strong>True<\/strong> is far from being unique to Delphi.<\/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\">&lt; 1<\/span> <span class=\"rt-label rt-postfix\">minutes]<\/span><\/span> My most recent posts have prompted a bit of discussion, and it seems some concern, regarding the implementation of Boolean values in Delphi. The concern at least I think is unwarranted, as long as you avoid explicitly comparing a Boolean value to the True constant and allow the compiler to logically evaluate the Boolean itself. [&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":true,"jetpack_social_options":[]},"categories":[4],"tags":[316,292,13],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p1TKYv-G1","jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":2597,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/2597\/","url_meta":{"origin":2605,"position":0},"title":"(True = 1) and (True = &#8216;-1&#8217;) ?","date":"17 Mar 2017","format":false,"excerpt":"It has been observed that the Delphi documentation states that the constants True and False have the values 1 and 0 respectively, not the -1 and 0 that the default string conversions apply. This does actually make sense but also lays a trap for the unwary. True, True, Wherefore Art\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2584,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/2584\/","url_meta":{"origin":2605,"position":1},"title":"Anatomy of a utility function:  BoolToStr()","date":"16 Mar 2017","format":false,"excerpt":"Jaap Van Goor was asking on FaceBook about some seemingly strange behaviour when obtaining string representations of Booleans using the Delphi RTL, which led me to revisit some familiar (and some not so familiar) old Delphi ground and take a look at the area involved in further detail. First of\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":706,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/706\/","url_meta":{"origin":2605,"position":2},"title":"Making a case for Strings, the sane way","date":"02 Dec 2010","format":false,"excerpt":"Lars Fosdal responded to my previous post suggesting a way of implementing string support in a case-like construct (but not actually a case statement) using generics and anonymous methods. All very clever, but way, way too complicated and - if you don't mind me saying so - as ugly as\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2265,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/2265\/","url_meta":{"origin":2605,"position":3},"title":"Nullable Types.  Not!","date":"23 Aug 2014","format":false,"excerpt":"I recently mentioned that RemObjects have placed their OS X native IDE - a.k.a. Fire - into public beta. I haven't been using it myself (yet) but have been following developments in the RemObjects Talk forums with interest, and a new feature in the Elements 8.0 compiler (also part of\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2337,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/2337\/","url_meta":{"origin":2605,"position":4},"title":"A Silent Danger&#8230;","date":"07 Jun 2015","format":false,"excerpt":"A brief post on a long standing omission in type checking in Pascal and the limitations of Range Checking as applied to the problem. Consider this contrived example of a simple function: This very simple function accepts an explicitly 32-bit Integer parameter and simply returns TRUE if the value passed\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2164,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/2164\/","url_meta":{"origin":2605,"position":5},"title":"Smoketest &#8211; Some Differences With DUnit","date":"19 Nov 2013","format":false,"excerpt":"Writing tests in Smoketest is intended to enable a test developer to write tests in a way that describe themselves, without requiring the test developer to add this \"narrative\" themselves. To see this in action, I thought I would compare some simple DUnit tests with the equivalent using the Smoketest\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/2605"}],"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=2605"}],"version-history":[{"count":2,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/2605\/revisions"}],"predecessor-version":[{"id":2607,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/2605\/revisions\/2607"}],"wp:attachment":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/media?parent=2605"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/categories?post=2605"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/tags?post=2605"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}