{"id":1167,"date":"2013-03-27T15:55:17","date_gmt":"2013-03-27T05:55:17","guid":{"rendered":"http:\/\/brnz.org\/hbr\/?p=1167"},"modified":"2013-03-27T15:56:11","modified_gmt":"2013-03-27T05:56:11","slug":"bugs-of-the-day-tuesday-2013-03-26","status":"publish","type":"post","link":"https:\/\/brnz.org\/hbr\/?p=1167","title":{"rendered":"Bugs of the day, Tuesday 2013-03-26"},"content":{"rendered":"<p>One bug, and one better solution to a previous bug.<\/p>\n<h2>Local static state is local, static<\/h2>\n<pre escaped=\"true\" lang=\"cpp\">int Foo() {\r\n  static int timeout = kTimeoutLimit;\r\n  bool polled_condition = CheckExternalCondition();\r\n  if( !polled_condition )\r\n    --timeout;\r\n  if( timeout == 0 ) { \r\n    printf(\"condition not set before timeout\");\r\n    return kTaskFailed;\r\n  }\r\n  if( polled_condition )\r\n    return kTaskComplete;\r\n  else\r\n    return kTaskIncomplete;\r\n}\r\nvoid Bar() { \r\n  while( Foo() == kTaskIncomplete );\r\n}<\/pre>\n<p><span style=\"line-height: 1.714285714; font-size: 1rem;\">Sometimes a local static variable is a useful thing &#8212; conveniently quick to add to any piece of code, and localized to a particular scope. You know everything about what can happen to it during its entire lifetime &#8212; assuming you know about how the scope it is contained within operates. (and I&#8217;m disregarding the returning of references to local static variables from a function. That&#8217;s a whole different bag of fun&#8230;)<\/span><\/p>\n<p>Quickly rewriting some code today, I added a local static counter &#8212; counting down each time a desired condition was not met, and triggering a <strong>printf()<\/strong> should the count ever reach zero. I was using this to diagnose that something unexpected had happened, and that some event had not taken place.<\/p>\n<p>The above code should work adequately well &#8212; if <strong>Bar()<\/strong> is only ever run once (and only from one thread at a time &#8212; but that&#8217;s not the issue here). <strong>timeout<\/strong>\u00a0is never reset, so unless <strong>CheckExternalCondition()<\/strong> returns\u00a0true, first time, every time, the value in <strong>timeout<\/strong> will continue to decrease with each run of <strong>Bar()<\/strong>. If it drops below zero, there will no longer be a limit on the on how long <strong>Foo()<\/strong> can loop.<\/p>\n<p>A fix here is to make sure timeout is reset each time <strong>Foo()<\/strong> &#8220;completes&#8221; i.e. when it returns <strong>kTaskComplete<\/strong> or <strong>kTaskFailed<\/strong>.<\/p>\n<p>More generally, this does not seem like a good use of a static local variable &#8212; relevant context for the function is not readily apparent within the function, so it seems better to store the timeout value outside of <strong>Foo()<\/strong>.<\/p>\n<p>(The actual code is more convoluted than the example above, so it&#8217;s not quite as simple as adding a local timeout var in <strong>Bar()<\/strong>, but only just)<\/p>\n<h2>Redux:\u00a0<a title=\"Bugs of the day,  Tuesday 2013-03-19\" href=\"https:\/\/brnz.org\/hbr\/?p=1114\">Changed virtual function prototype results in correct function not being called<\/a><\/h2>\n<p><span style=\"line-height: 1.714285714; font-size: 1rem;\">This was a bug where I changed the prototype for a virtual function, but that classes with the old prototype would not be detected at compile time and would silently do nothing should the virtual function be called. Read the details via the link above.<\/span><\/p>\n<p>I had added an assert to catch any classes that didn&#8217;t have the new version of the function, but that only worked at runtime, and only when the function was actually called. What I really wanted for this was a compile-time check that was more reliable than the inheriting programmer remembering to use <strong>override<\/strong>.\u00a0I discovered that there is a way to do this with C++11: <strong>final<\/strong>.<\/p>\n<pre escaped=\"true\" lang=\"c++\">class Base {\r\npublic:\r\n\u00a0 virtual void Foo(int some_param, WhatsitType some_other_param) \u00a0{ \u00a0}\r\nprivate:\r\n  virtual void Foo(int) <strong>final<\/strong> { }\r\n};<\/pre>\n<p>With this, anything that inherits from <strong>Base<\/strong> and attempts to define its own <strong>void Foo(int)<\/strong> method will result in a compile error. I&#8217;m much happier with this, and making this change revealed some extra instances of the old function that I&#8217;d missed in my previous sweep. Huzzah.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>One bug, and one better solution to a previous bug. Local static state is local, static int Foo() { static int timeout = kTimeoutLimit; bool polled_condition = CheckExternalCondition(); if( !polled_condition ) &#8211;timeout; if( timeout == 0 ) { printf(&#8220;condition not set before timeout&#8221;); return kTaskFailed; } if( polled_condition ) return kTaskComplete; else return kTaskIncomplete; } &hellip; <a href=\"https:\/\/brnz.org\/hbr\/?p=1167\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Bugs of the day, Tuesday 2013-03-26&#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\/1167"}],"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=1167"}],"version-history":[{"count":5,"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=\/wp\/v2\/posts\/1167\/revisions"}],"predecessor-version":[{"id":1171,"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=\/wp\/v2\/posts\/1167\/revisions\/1171"}],"wp:attachment":[{"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1167"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1167"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/brnz.org\/hbr\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1167"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}