{"id":1159,"date":"2013-03-26T15:37:00","date_gmt":"2013-03-26T05:37:00","guid":{"rendered":"http:\/\/brnz.org\/hbr\/?p=1159"},"modified":"2013-03-26T15:37:00","modified_gmt":"2013-03-26T05:37:00","slug":"bugs-of-the-day-monday-2013-03-25","status":"publish","type":"post","link":"https:\/\/brnz.org\/hbr\/?p=1159","title":{"rendered":"Bugs of the day, Monday 2013-03-25"},"content":{"rendered":"<h2>Initialized, but not in the right order<\/h2>\n<p>One runtime bug today, being fallout from an attempted fix for Friday&#8217;s <a title=\"Bugs of the day 2013-03-22\" href=\"https:\/\/brnz.org\/hbr\/?p=1139\"><strong>Unexpected use of class<\/strong><\/a> bug.<\/p>\n<p>To recap\/elaborate: I changed something like this<\/p>\n<pre escaped=\"true\" lang=\"cpp\">struct Foo : public Baz {\r\n\u00a0 Bar* m_Bar;\r\n\u00a0 virtual void Destroy() override { }\r\n};<\/pre>\n<p><span style=\"line-height: 1.714285714; font-size: 1rem;\">to be something more like this<\/span><\/p>\n<pre escaped=\"true\" lang=\"cpp\">struct Foo : public Baz {\r\n\u00a0 Bar* m_Bar;\r\n\u00a0 virtual void Destroy() override { m_Bar-&gt;Destroy(); }\r\n};<\/pre>\n<p><span style=\"line-height: 1.714285714; font-size: 1rem;\">and I had assumed this would be OK because I [thought that I] knew the only place that <\/span><strong style=\"line-height: 1.714285714; font-size: 1rem;\">Foo<\/strong><span style=\"line-height: 1.714285714; font-size: 1rem;\">s would be created, which would always safely initialize <strong>m_Bar<\/strong>.<\/span><\/p>\n<p>Unfortunately, there is another way to construct these objects with some unexpected (bad) input data that would not initialize <strong>m_Bar<\/strong>. In such a case, <strong>Foo::Destroy()<\/strong> would crash because <strong>m_Bar<\/strong> pointed at who-knows-what.<\/p>\n<p>So I implemented something like<\/p>\n<pre escaped=\"true\" lang=\"cpp\">struct Foo : public Baz {\r\n\u00a0 Bar* m_Bar;\r\n\u00a0 virtual void Init() override { m_Bar = NULL; }\r\n\u00a0 virtual void Destroy() override {\r\n\u00a0 \u00a0 if( m_Bar != NULL)\r\n\u00a0 \u00a0 \u00a0 m_Bar-&gt;Destroy();\r\n\u00a0 \u00a0 else\r\n\u00a0 \u00a0 \u00a0 HARD_TO_MISS_NOTIFICATION( USEFUL_WARNING_37 );\r\n\u00a0 }\r\n};<\/pre>\n<p>&#8220;Hooray,&#8221; I thought. &#8220;That will catch those pesky bad datas.&#8221;<\/p>\n<p>In practice what I got was a crash from the first thing that tried to use <strong>m_Bar<\/strong>.<\/p>\n<p>It turns out that the construction path for <strong>Foo<\/strong>s sets up <strong>m_Bar<\/strong> before calling <strong>Foo::Init()<\/strong>, so now our correctly constructed <strong>Foo<\/strong>\u00a0object has it&#8217;s valid data overwritten by an overzealous initialization function.<\/p>\n<p><strong>Foo::Init()<\/strong> is called from both the preferred and not-preferred construction paths, so my hope had been to fix it there and catch use of the not-preferred path, but this didn&#8217;t work. My next thought was to reorder the setup of <strong>m_Bar<\/strong> and the call to <strong>Init()<\/strong>, but that seemed far too risky &#8212; there are a lot of subclasses of <strong>Foo<\/strong>, and many of them have non-trivial <strong>Init()<\/strong> overrides of their own, so there is a high probability that something else will break if <strong>m_Bar<\/strong> is not set up before the call to <strong>Init()<\/strong>.<\/p>\n<p>The winner this time seems to be to initialize the member to zero using: a constructor. Yes, it&#8217;s probably the obvious option, but for much of this codebase explicit <strong>Init()<\/strong> functions are used instead of constructors. Fortunately, for <strong>Foo<\/strong> and its friends (sub classes, parent class) we call the constructor (via placement new) to set up the vtable for us, so we can use it to also initialize the <strong>m_Bar<\/strong> pointer and consequently help catch occurrences of bad data in a less fatal fashion.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Initialized, but not in the right order One runtime bug today, being fallout from an attempted fix for Friday&#8217;s Unexpected use of class bug. To recap\/elaborate: I changed something like this struct Foo : public Baz { \u00a0 Bar* m_Bar; \u00a0 virtual void Destroy() override { } }; to be something more like this struct &hellip; <a href=\"https:\/\/brnz.org\/hbr\/?p=1159\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Bugs of the day, Monday 2013-03-25&#8221;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[26],"tags":[],"_links":{"self":[{"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=\/wp\/v2\/posts\/1159"}],"collection":[{"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1159"}],"version-history":[{"count":2,"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=\/wp\/v2\/posts\/1159\/revisions"}],"predecessor-version":[{"id":1161,"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=\/wp\/v2\/posts\/1159\/revisions\/1161"}],"wp:attachment":[{"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1159"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1159"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1159"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}