{"id":27163,"date":"2007-04-23T10:00:00","date_gmt":"2007-04-23T10:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2007\/04\/23\/psychic-debugging-when-reading-unfamiliar-code-assume-its-mostly-correct\/"},"modified":"2007-04-23T10:00:00","modified_gmt":"2007-04-23T10:00:00","slug":"psychic-debugging-when-reading-unfamiliar-code-assume-its-mostly-correct","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20070423-00\/?p=27163","title":{"rendered":"Psychic debugging: When reading unfamiliar code, assume it&#039;s mostly correct"},"content":{"rendered":"<p>\nYou may be called in to study a problem in code you&#8217;ve never seen before\nor be asked to look over a proposed change to some code you&#8217;ve never\nseen before.\nWhen this happens, you have to take shortcuts in your analysis\nbecause following every function call to the bottom would not only\ntake far too much time,\nbut also take you so far away from the code in question\nthat you will probably forget what you were looking for in the\nfirst place.\n<\/p>\n<p>\nFor example, suppose you&#8217;re looking at some code that goes\nlike this:\n<\/p>\n<pre>\n...\nGizmo *gizmo = get_gizmo_from_name(name);\nif (gizmo) {\n Gizmo *parent = gizmo-&gt;get_parent();\n parent-&gt;set_height(newheight);\n ...\n}\n<\/pre>\n<p>\nYou might have some questions about this code.<\/p>\n<ul>\n<li>What if <code>name<\/code> is <code>NULL<\/code>?\nIs it legal to pass <code>NULL<\/code> to <code>get_gizmo_from_name<\/code>?<\/p>\n<li>What if the <code>gizmo<\/code> doesn&#8217;t have a parent?\n    Is there a potential <code>NULL<\/code> pointer dereference here?<\/p>\n<li>Are the <code>gizmo<\/code> and <code>parent<\/code> reference-counted?\n    Did we need to do something like <code>gizmo-&gt;Release()<\/code> or a\n    <code>parent-&gt;Release()<\/code> to keep the reference counts\n    in balance and avoid a memory leak?\n<\/ul>\n<p>\nFinding the answers to these questions may take some time.\nFor example, you might have access only to the diff and not\nto the entire project,\nor a grep for the definition of\n<code>get_gizmo_from_name<\/code> in the same directory that has\nthe function in question doesn&#8217;t turn up anything\nand you have to expand your search wider and wider\nin an attempt to find it.\n<\/p>\n<p>\nThis is when you invoke the &#8220;Assume it&#8217;s mostly correct&#8221; heuristic.\nThe theory behind this heuristic is that whoever wrote this code\nhas a better understanding of how it works than you do.\n(This is a pretty safe bet\nsince your knowledge of this code is approximately zero.)\nThe problem you&#8217;re looking for is probably some small detail,\nan edge case, a peculiar combination of circumstances.\nYou can assume that the common case is pretty solid;\nif the common case were also broken,\nthe problem would be so obvious that they wouldn&#8217;t need to ask\nan outsider for help.\n<\/p>\n<p>\nTherefore, look at the other parts of the code.\nFor example, you might find a code fragment nearby like this one:\n<\/p>\n<pre>\n \/\/ rename the gizmo\n Gizmo *gizmo = get_gizmo_from_name(oldname);\n if (gizmo) {\n  gizmo-&gt;set_name(newname);\n }\n<\/pre>\n<p>\nThat already answers two of your questions.\nFirst, you don&#8217;t have to worry about checking the name\nagainst <code>NULL<\/code> because this code fragment doesn&#8217;t check,\nand by the heuristic, the code is mostly correct.\nTherefore, <code>NULL<\/code> is most likely an acceptable parameter\nfor the <code>get_gizmo_from_name<\/code> function.\nBecause if it weren&#8217;t, then that code would be broken too!\n(This is sort of the counterexample to what Mom always told you:\nIf everybody else jumped off a bridge,\nthen it is probably okay to jump off bridges.)\n<\/p>\n<p>\nSecond, this code doesn&#8217;t do anything special when it&#8217;s done\nwith the <code>gizmo<\/code> so it&#8217;s probably okay just to abandon\nthe <code>gizmo<\/code> without need to do any special reference\ncount management.\nBecause if you had to dispose of it in a special way,\nthen that code would be broken too!\n<\/p>\n<p>\nNow, of course, this heuristic can be fooled,\nbut if you&#8217;re operating with only partial information,\nit&#8217;s often the best you can do.\nGet it right often enough and people will believe that you too\nhave psychic debugging powers.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>You may be called in to study a problem in code you&#8217;ve never seen before or be asked to look over a proposed change to some code you&#8217;ve never seen before. When this happens, you have to take shortcuts in your analysis because following every function call to the bottom would not only take far [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[26],"class_list":["post-27163","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-other"],"acf":[],"blog_post_summary":"<p>You may be called in to study a problem in code you&#8217;ve never seen before or be asked to look over a proposed change to some code you&#8217;ve never seen before. When this happens, you have to take shortcuts in your analysis because following every function call to the bottom would not only take far [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/27163","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=27163"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/27163\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=27163"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=27163"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=27163"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}