{"id":21,"date":"2014-10-09T14:35:32","date_gmt":"2014-10-09T11:35:32","guid":{"rendered":"http:\/\/blog.dmmedia.org\/en\/?p=21"},"modified":"2014-10-29T10:04:13","modified_gmt":"2014-10-29T07:04:13","slug":"danger-of-using-default-values-in-declarations","status":"publish","type":"post","link":"https:\/\/blog.dmmedia.org\/en\/danger-of-using-default-values-in-declarations\/","title":{"rendered":"Danger of using default values in declarations"},"content":{"rendered":"<p>Working on a large project using C++, recently faced a dangerous things during<br \/>\ndebugging. Let&#8217;s see in examples. Once there was a method:<\/p>\n<blockquote>\n<pre>Class1::SetEditBox(CString const&amp; value, bool isUppercase = true);<\/pre>\n<\/blockquote>\n<p>Somewhere it was used differently:<\/p>\n<blockquote>\n<pre>obj1.SetEditBox(_T(\"Volume\"), false);\r\n ...\r\n obj2.SetEditBox(_T(\"SerialNo\"));<\/pre>\n<\/blockquote>\n<p>After a while this declaration was a bit extended:<\/p>\n<blockquote>\n<pre>Class1::SetEditBox(CString const&amp; value, bool isEditable = false, bool isUppercase = true);<\/pre>\n<\/blockquote>\n<p>New places were using it properly, but not all that old places were changed, so<\/p>\n<blockquote>\n<pre>obj1.SetEditBox(_T(\"Volume\"), false);<\/pre>\n<\/blockquote>\n<p>became to have isUppercase = true, however, since volume is usually numeric,<br \/>\nthis was not detected during &#8220;happy way&#8221; testing.<br \/>\nMeanwhile system became more complex. Refactored and rewritten, developers were<br \/>\nalso changing. Inheritance and other OOP stuff started to using this method:<\/p>\n<blockquote>\n<pre>Class2::SetListEdit(CString const&amp; value, bool isEditable = false, bool isUppercase = true)\r\n{\r\n    \/\/ ...\r\n    obj4.SetEditBox(value, isEditable, isUppercase);\r\n    \/\/ ...\r\n}<\/pre>\n<\/blockquote>\n<p>And again time passed, things changed, and so changed method declaration:<\/p>\n<blockquote>\n<pre>Class1::SetEditBox(CString const&amp; value, bool isNumeric = true, bool isEditable = false, bool isUppercase = true);<\/pre>\n<\/blockquote>\n<p>Now there were even more things to recheck and update, but guess what?<br \/>\nSomebody, who did this change did not care about looking up every place to change<br \/>\nand now it became the bug, which I called &#8220;Shifting Boolean&#8221;:<\/p>\n<blockquote>\n<pre>Class3::AddListEdit(CString const&amp; value, bool isUppercase = true)\r\n{\r\n    Class2 obj5;\r\n    obj5.SetListEdit(value, isUppercase);\r\n}<\/pre>\n<\/blockquote>\n<p>So the call to Class3::AddListEdit() and passing only CString value, made<br \/>\nisUppercase default value bacame isEditable in Class2::SetListEdit() and then<br \/>\nto became isNumeric in Class1::SetEditBox().<\/p>\n<p>If there were no default values, all the differences would come out during<br \/>\ncompilation, or even earlier, in IDE. However there are a trade-offs: either<br \/>\nyou save typing and introduce default values, or make changes more transparent.<\/p>\n<p>In any case, every change that can be interpreted by implicit type conversion<br \/>\nshould be carefully examined and all the places should be changed as required.<\/p>\n<p>It took me about 6 hours to refactor all the project code and get rid of this<br \/>\nbug. In my solution I have replaced booleans with a single enum argument, because<br \/>\nall the booleans were tightly coupled, and in the end switch()-ing between<br \/>\nenumerated values was easier than checking all the boolean combinations.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Working on a large project using C++, recently faced a dangerous things during debugging. Let&#8217;s see in examples. Once there was a method: Class1::SetEditBox(CString const&amp; value, bool isUppercase = true); Somewhere it was used differently: obj1.SetEditBox(_T(&#8220;Volume&#8221;), false); &#8230; obj2.SetEditBox(_T(&#8220;SerialNo&#8221;)); After a while this declaration was a bit extended: Class1::SetEditBox(CString const&amp; value, bool isEditable = false, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[3],"class_list":["post-21","post","type-post","status-publish","format-standard","hentry","category-programming","tag-c"],"_links":{"self":[{"href":"https:\/\/blog.dmmedia.org\/en\/wp-json\/wp\/v2\/posts\/21","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.dmmedia.org\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.dmmedia.org\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.dmmedia.org\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.dmmedia.org\/en\/wp-json\/wp\/v2\/comments?post=21"}],"version-history":[{"count":1,"href":"https:\/\/blog.dmmedia.org\/en\/wp-json\/wp\/v2\/posts\/21\/revisions"}],"predecessor-version":[{"id":22,"href":"https:\/\/blog.dmmedia.org\/en\/wp-json\/wp\/v2\/posts\/21\/revisions\/22"}],"wp:attachment":[{"href":"https:\/\/blog.dmmedia.org\/en\/wp-json\/wp\/v2\/media?parent=21"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.dmmedia.org\/en\/wp-json\/wp\/v2\/categories?post=21"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.dmmedia.org\/en\/wp-json\/wp\/v2\/tags?post=21"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}