<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Fri, Jul 27, 2018 at 1:06 PM, Ryan Joseph <span dir="ltr"><<a href="mailto:ryan@thealchemistguild.com" target="_blank">ryan@thealchemistguild.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">I had no idea you could do that!<br></blockquote><div><br></div><div>Obviously, it speaks high of your abilities ;)</div><div>You've been able to accomplish your tasks without use of hacks (of any kind), playing strict by the rules.</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">I’m totally confused now. Since when was it ok to call methods on nil objects? According to this test not only can you call methods on nil objects but it calls the method statically (like a class method), i.e the test prints “DoThis”. How is that possible?<br></blockquote><div><br></div><div>From the low-level (virtual/physical memory, CPU) perspective you can do that at any time on either nil-ed or uninitialized object as long as the method doesn't try to access and invalid memory.</div><div><br></div><div>The example (compiled for i386 and not using -CR works as expected)</div><div><br></div><div><div>type</div><div>  TRobust = class(TObject)</div><div>  public</div><div>    v : Integer;</div><div>    function Max(a,b: Integer): Integer;</div><div>  end;</div><div><br></div><div>function TRobust.Max(a,b: Integer): Integer;</div><div>begin</div><div>  if a>b then Result:=a</div><div>  else Result:=b;</div><div>end;</div><div><br></div><div>var</div><div>  r : TRobust;</div><div>begin</div><div>  r := nil;</div><div>  writeln(r.Max(5,10));</div><div>end.  </div></div><div> </div><div>However such behavior, would be RTL specific - it's all about how the compiler would generate such call. If it would attempt to access any field (i.e. VMT) related to the instance of the object itself (rather than the class), there's a high chance it would fail.</div><div><br></div><div>And that's why having -CR enabled during development is generally a very good idea.</div><div><br></div><div>From high-level (OOP) such actions are not welcomed (and are enforced using -CR in case of FPC).</div><div><br></div><div>In order to have robust, maintainable and portable (to either other platform or even language) a developer should respect high-level rules and never depend on low-level rules to be the same on any platform.<br></div><div><br></div><div>thanks,</div><div>Dmitry</div></div></div></div>