{"id":833,"date":"2011-12-12T20:24:40","date_gmt":"2011-12-12T08:24:40","guid":{"rendered":"https:\/\/www.deltics.co.nz\/blog\/?p=833"},"modified":"2011-12-12T20:28:22","modified_gmt":"2011-12-12T08:28:22","slug":"respect-your-ancestors","status":"publish","type":"post","link":"https:\/\/www.deltics.co.nz\/blog\/posts\/833\/","title":{"rendered":"Respect Your Ancestors"},"content":{"rendered":"<span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">[Estimated Reading Time: <\/span> <span class=\"rt-time\">2<\/span> <span class=\"rt-label rt-postfix\">minutes]<\/span><\/span><p>Yesterday I posted <a href=\"https:\/\/plus.google.com\/u\/0\/111874043401122099650\/posts\">an observation on Google+, lamenting the lack of a compiler warning when code in an overridden method failed to call any inherited implementation<\/a>.  This simple oversight in an <strong>AfterConstruction<\/strong> override in a situation where the observed bug that arose (a memory leak) could just as easily have been the consequence of a more complex error on my part, caused me to spend a significant amount of time, hunting down the <em>wrong bug<\/em>.<br \/>\n<!--more--><\/p>\n<p><a href=\"https:\/\/plus.google.com\/u\/0\/118329774029340938562\/posts\">Eric Grange<\/a> suggested that <strong>AfterConstruction<\/strong> and <strong>BeforeDestruction<\/strong> was best forgotten.  This was an interesting thought, but when I considered it I concluded that I had to disagree.  Not only would it not help me avoid my problem had I ignored them, but doing so would merely have created new opportunities to introduce such time-wasting bugs.<\/p>\n<p><strong>AfterConstruction<\/strong> and <strong>BeforeDestruction<\/strong> fulfil a genuine need imho.  Most especially I have found them of immense utility when creating frameworks.  In a framework I find I often have a base class (or classes) from which further classes are intended to be derived, with (potentially) overridden constructors.  Also quite often, the base class never-the-less requires some internal initialisation to reliably occur only after any overridden construction has been completed.<\/p>\n<p>In the specific case that led to my initial post, the base class in question contained an interface reference counting bug fix I originally developed long before it was fixed in the VCL.  Actually, it addresses a duo of bugs, one of which manifests during construction and the other during destruction.  From memory (my Windows VM is not currently running so I can&#8217;t check the VCL source to be certain), the VCL now addresses the constructor side of things but not the destructor.<\/p>\n<p>In any event, my base class incorporates a <strong>NewInstance<\/strong> override (effectively <em>BeforeConstruction<\/em>) and an accompanying <strong>AfterConstruction<\/strong> implementation that operated to ensure a positive reference count during the execution of those constructors.  This addresses the situation where an object references itself using an interface during construction (e.g. passing a reference to itself to some other object which then discards it) resulting in the reference count &#8220;bouncing&#8221;, falling back to zero and thus destroying itself.  A similar mechanism using <strong>BeforeDestruction<\/strong> ensures that &#8220;double-destruction&#8221; doesn&#8217;t occur if self is reference as an interface during <em>destructor<\/em> execution).<\/p>\n<p>If <strong>AfterConstruction<\/strong> and <strong>BeforeDestruction<\/strong> didn&#8217;t exist (or you ignored them) then in such circumstances you would simply have to contrive your own exactly <em>equivalent<\/em> mechanism.  This mechanism would still &#8211; by necessity &#8211; rely on <em>virtual<\/em> methods and <em>override<\/em>s and so as far as I can see will <em>still be vulnerable to the omission of calls to the inherited implementation<\/em>.<\/p>\n<p>But worse, without it being implemented in the base framework further steps would most likely be required to ensure that the alternate mechanism was correctly invoked.  As far as I can see, ignoring the provided core mechanism and &#8220;rolling your own&#8221;  would only compound the problem, increasing the potential to introduce a mistake rather than reducing it.<\/p>\n<p>Setting aside the rights or wrongs of an <strong>AfterConstruction<\/strong> or <strong>BeforeDestruction<\/strong> mechanism in the specific, in the general case overriding a method and then neglecting to call &#8220;inherited&#8221; is a sufficiently rare occurrence that it would be worth warning about imho.<\/p>\n<p>Furthermore, the compiler directive(s) required to then silence that warning would provide a self documenting and clear signal that the omission is indeed intentional, expected and indeed required (in those rare cases that it genuinely is).<\/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\">2<\/span> <span class=\"rt-label rt-postfix\">minutes]<\/span><\/span> Yesterday I posted an observation on Google+, lamenting the lack of a compiler warning when code in an overridden method failed to call any inherited implementation. This simple oversight in an AfterConstruction override in a situation where the observed bug that arose (a memory leak) could just as easily have been the consequence of a [&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,133],"tags":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p1TKYv-dr","jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":1240,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/1240\/","url_meta":{"origin":833,"position":0},"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":716,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/716\/","url_meta":{"origin":833,"position":1},"title":"Delphi [Non]Starter Edition: No VCL Source!","date":"03 Feb 2011","format":false,"excerpt":"After an initial welcome (and purchase!) I find myself having to curb my initial enthusiasm. \u00a0Most of the omissions from the Starter Edition, as compared to the Professional and higher editions, make perfect sense and are in fact pretty much what I myself described as appropriate for a \"Community Edition\"\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":443,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/443\/","url_meta":{"origin":833,"position":2},"title":"Do You Know The Way To San Jose?","date":"29 Apr 2009","format":false,"excerpt":"So I thought everybody would know what I meant by that question, but the poll that I'm currently running suggests not, so perhaps I'd better explain. San Jose (California) is the setting for DelphiLive! the first actual, physical, honest to goodness in-your-face, face-TO-face major Delphi developer conference for mumble years.\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":750,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/750\/","url_meta":{"origin":833,"position":3},"title":"XE2 FireMonkey Designer &#8211; Clipboard Gotcha","date":"06 Sep 2011","format":false,"excerpt":"We are still waiting for our XE2 licenses to be organised but in the meantime I have started playing around with the Free Trial Edition. I haven't had much time to form much of an opinion as yet, but have already identified some oddities in the FireMonkey Form Designer, specifically\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2011-09-06-at-9.48.39-AM.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":825,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/825\/","url_meta":{"origin":833,"position":4},"title":"Class Helpers &#8211; A Hackers Cloak of Respectability","date":"09 Nov 2011","format":false,"excerpt":"Mat DeLong just posted another great example of when not to abuse class helpers in Delphi (though I should add that he didn't seem to see it that way). :) But you don't need helpers to do what this technique achieves, and in my view you really shouldn't be using\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":375,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/375\/","url_meta":{"origin":833,"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\/833"}],"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=833"}],"version-history":[{"count":4,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/833\/revisions"}],"predecessor-version":[{"id":837,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/833\/revisions\/837"}],"wp:attachment":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/media?parent=833"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/categories?post=833"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/tags?post=833"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}