{"id":26283,"date":"2007-06-25T10:00:00","date_gmt":"2007-06-25T10:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2007\/06\/25\/theres-no-point-improving-the-implementation-of-a-bad-idea\/"},"modified":"2007-06-25T10:00:00","modified_gmt":"2007-06-25T10:00:00","slug":"theres-no-point-improving-the-implementation-of-a-bad-idea","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20070625-00\/?p=26283","title":{"rendered":"There&#039;s no point improving the implementation of a bad idea"},"content":{"rendered":"<p>\n<a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2006\/09\/27\/773741.aspx\">\n<code>IsBadXxxPtr<\/code> is a bad idea and you shouldn&#8217;t call it<\/a>.\nIn the comments, many people proposed changes to the function to\nimprove the implementation.\nBut what&#8217;s the point?\n<code>IsBadXxxPtr<\/code> is just a bad idea.\nThere&#8217;s no point improving the implementation of a bad idea.\n<\/p>\n<p>\nOn the other hand, some people suggested making it clear that\n<code>IsBadXxxPtr<\/code> is a bad idea by making it <strong>worse<\/strong>.\nWhile this is tempting in a &#8220;I&#8217;m forcing you to do the right thing&#8221;\nsense, it carries with it serious compatibility problems.\n<\/p>\n<p>\nThere&#8217;s a lot of code that uses <code>IsBadXxxPtr<\/code> even though\nit&#8217;s a bad idea, and making <code>IsBadXxxPtr<\/code> worse would\nrisk breaking those programs that managed to get away with it up\nuntil now.\nThe danger of this is that people would upgrade to the next version\nof Windows and their program would stop working.\nWho do you think the blame will be placed on?\n<\/p>\n<p>\nSure, you might tell these people,\n&#8220;That&#8217;s because it&#8217;s a bug in your program.\nGo contact the vendor for an update.&#8221;\nOf course, that&#8217;s assuming you can prove that the reason why\nthe program stopped working was this <code>IsBadXxxPtr<\/code> stuff.\nHow can you tell that that was the problem?\nMaybe it was caused by some other problem,\npossibly even a bug in Windows itself.\nOr is your answer just going to be &#8220;Any program that crashes\nmust be crashing due to misuse of <code>IsBadXxxPtr<\/code>?&#8221;\n<\/p>\n<p>\nAnd, as I&#8217;ve noted before, contacting the vendor may not be enough.\nMost large corporations have programs that run their day-to-day\noperations.\nSome of them may have been written by a consultant ten years ago.\nEven if they have the source code, they may not have the expertise,\nresources, or simply inclination go to in and fix it.\nThis happens more often than you think.\nTo these customers, the behavior change is simply a regression.\n<\/p>\n<p>\nEven if you have the source code and expertise, fixing the problem\nmay not be as simple as it looks.\nYou may have designed your program poorly and relied on\n<code>IsBadXxxPtr<\/code> to cover for your failings.\nFor example, you may have decided that\n&#8220;The <code>lParam<\/code> to this message is a pointer to\na <code>CUSTOMER<\/code> structure, or it could just be\nthe customer ID number.\nI&#8217;ll use <code>IsBadReadPtr<\/code>, and if the pointer is bad,\nthen the value must be the customer ID number.&#8221;\nOr you\n<a HREF=\"http:\/\/blogs.msdn.com\/ericlippert\/archive\/2006\/09\/27\/774117.aspx\">\nmay have changed the definition of a function parameter<\/a>\nand now need to detect whether your caller is calling the &#8220;old function&#8221;\nor the &#8220;new one&#8221;.\nOr it could simply be that once you remove the call to\n<code>IsBadXxxPtr<\/code>, your program crashes constantly\nbecause the <code>IsBadXxxPtr<\/code> was covering up for\na huge number of other programming errors (such as uninitialized\nvariables).\n<\/p>\n<p>\n&#8220;But what if I&#8217;m just using it for debugging purposes?&#8221;\nFor debugging purposes, allow me to propose the following\ndrop-in replacement functions:\n<\/p>\n<pre>\ninline BOOL IsBadReadPtr2(CONST VOID *p, UINT_PTR cb)\n{\n  memcmp(p, p, cb);\n  return FALSE;\n}\ninline BOOL IsBadWritePtr2(LPVOID p, UINT_PTR cb)\n{\n  memmove(p, p, cb);\n  return FALSE;\n}\n<\/pre>\n<p>\nIt&#8217;s very simple: To see if a pointer is bad for reading,\n<strong>just read it<\/strong> (and similarly writing).\nIf the pointer is bad, the read (or write) will raise an exception,\nand then you can investigate the bad pointer at the point it\nis found.\nWe read from the memory by comparing it to itself\nand write to the memory by copying it to itself.\nThese have no effect but they do force the memory to be\nread or written.\nOf course, this trick assumes that the compiler didn&#8217;t optimize\nout the otherwise pointless &#8220;compare memory to itself&#8221;\nand &#8220;copy memory to itself&#8221; operations.\n(Note also that the replacement <code>IsBadWritePtr2<\/code>\nis not thread-safe, since another thread might be modifying the\nmemory while we&#8217;re copying it.\nBut then again, the original <code>IsBadWritePtr<\/code> wasn&#8217;t\nthread-safe either, so there&#8217;s no loss of amenity there.)\n<\/p>\n<p>\n(As an aside: I&#8217;ve seen people try to write replacements\nfor <code>IsBadXxxPtr<\/code> and end up introducing a bug along\nthe way.\nThere are many corner cases in this seemingly-simple family of\nfunctions.)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>IsBadXxxPtr is a bad idea and you shouldn&#8217;t call it. In the comments, many people proposed changes to the function to improve the implementation. But what&#8217;s the point? IsBadXxxPtr is just a bad idea. There&#8217;s no point improving the implementation of a bad idea. On the other hand, some people suggested making it clear that [&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-26283","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-other"],"acf":[],"blog_post_summary":"<p>IsBadXxxPtr is a bad idea and you shouldn&#8217;t call it. In the comments, many people proposed changes to the function to improve the implementation. But what&#8217;s the point? IsBadXxxPtr is just a bad idea. There&#8217;s no point improving the implementation of a bad idea. On the other hand, some people suggested making it clear that [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/26283","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=26283"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/26283\/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=26283"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=26283"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=26283"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}