{"id":21983,"date":"2008-06-11T10:00:00","date_gmt":"2008-06-11T10:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2008\/06\/11\/if-you-say-that-you-dont-care-about-something-you-shouldnt-be-upset-that-it-contains-garbage\/"},"modified":"2008-06-11T10:00:00","modified_gmt":"2008-06-11T10:00:00","slug":"if-you-say-that-you-dont-care-about-something-you-shouldnt-be-upset-that-it-contains-garbage","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20080611-00\/?p=21983","title":{"rendered":"If you say that you don&#039;t care about something, you shouldn&#039;t be upset that it contains garbage"},"content":{"rendered":"<p>\nThere are many situations where you pass a structure to a function,\nand the function fills in the structure with information you request.\nIn some cases, the function always fills in the entire structure\n(example: <code>GlobalMemoryStatus<\/code>).\nIn other cases, you tell the function\nwhich bits of information you care about,\nto save the function the effort of computing something you weren&#8217;t\ninterested in anyway\n(example: <code>TreeView_GetItem<\/code>).\n<\/p>\n<p>\nIn the latter case,\nif you say that you aren&#8217;t interested in certain parts of the structure,\nand then you change your mind and start paying attention to them,\ndon&#8217;t be surprised if you find that there&#8217;s nothing interesting there.\nAfter all, you said you didn&#8217;t care.\n<\/p>\n<p>\nFor example, if you call <code>TreeView_GetItem<\/code> and set the\nmask to <code>TVIF_IMAGE | TVIF_PARAM<\/code>,\nthis means that you want the function to set the\n<code>iImage<\/code> and <code>lParam<\/code> members of the\n<code>TVITEM<\/code> structure and that you don&#8217;t care about the rest.\nAfter the call returns, the values of those two members are defined,\nsince you said that&#8217;s what you wanted,\nand the remainder of the output fields are <i>undefined<\/i>.\nThey might contain useful information,\nthey might contain garbage,\nyou&#8217;re not supposed to care since you said that you didn&#8217;t.\n<\/p>\n<p>\nWhy might fields you said you didn&#8217;t care about still contain\ninformation (correct or incorrect)?\nIt might be that the value is so easy to compute that checking\nwhether the value should be set takes more work than actually\nsetting it!\nIn such a case, the function might choose to set the value even\nif you didn&#8217;t say that you needed it.\n<\/p>\n<p>\nOn the other hand, the value might be an artifact of a translation\nlayer:\nYou pass a structure saying, &#8220;I&#8217;m interested in two out of the four\nmembers.&#8221;\nThe function in turn calls a lower lever function with a different\nstructure, saying, &#8220;I&#8217;m interested in two out of the five members\nof this different structure.&#8221;\nAfter the call returns, the middle-man function converts the lower-level\nstructure to the higher-level structure.\nSure, it may also &#8220;convert&#8221; stuff that was never asked for,\nbut you said you weren&#8217;t interested, so they just get garbage.\nIn other words, the function you&#8217;re calling might be defined like this:\n<\/p>\n<pre>\n\/\/ The pinfo parameter points to this structure\nstruct FOOINFO {\n DWORD dwInUse;\n DWORD dwAvailable;\n DWORD dwRequested;\n DWORD dwDenied;\n};\n\/\/ The dwMask parameter can be a combination of these values\n#define FOOINFO_INUSE     0x0001\n#define FOOINFO_AVAILABLE 0x0002\n#define FOOINFO_REQUESTED 0x0004\n#define FOOINFO_DENIED    0x0008\nBOOL GetFooInfo(FOOINFO *pinfo, DWORD dwMask);\n<\/pre>\n<p>\nNow, the <code>GetFooInfo<\/code> function might just be a middle\nman that talks to another component to do the real work.\n<\/p>\n<pre>\n\/\/ lowlevel.h\nstruct LOWLEVELSTATS {\n DWORD dwUnitSize;\n DWORD dwUnitsInUse;\n DWORD dwUnitsAvailable;\n DWORD dwUnitsRequested;\n DWORD dwUnitsGranted;\n DWORD dwTotalRequests;\n};\n\/\/ The dwMask parameter can be a combination of these values\n#define LLSTATS_UNITSIZE  0x0001\n#define LLSTATS_INUSE     0x0002\n#define LLSTATS_AVAILABLE 0x0004\n#define LLSTATS_REQUESTED 0x0008\n#define LLSTATS_GRANTED   0x0020\n#define LLSTATS_REQUESTS  0x0040\nBOOL GetLowLevelStatistics(LOWLEVELSTATS *pstats, DWORD dwMask);\n<\/pre>\n<p>\nThe resulting <code>GetFooInfo<\/code> function merely\ntranslates the call from the application into a call to\nthe <code>GetLowLevelStatistics<\/code> function:\n<\/p>\n<pre>\nBOOL GetFooInfo(FOOINFO *pinfo, DWORD dwMask)\n{\n LOWLEVELSTATS stats;\n DWORD dwLowLevelMask = LLINFO_UNITSIZE;\n if (dwMask &amp; FOOINFO_INUSE)\n  dwLowLevelMask |= LLSTATS_INUSE;\n if (dwMask &amp; FOOINFO_AVAILABLE)\n  dwLowLevelMask |= LLSTATS_AVAILABLE;\n if (dwMask &amp; FOOINFO_REQUESTED)\n  dwLowLevelMask |= LLSTATS_REQUESTED;\n if (dwMask &amp; FOOINFO_DENIED)\n  dwLowLevelMask |= LLSTATS_REQUESTED | LLSTATS_GRANTED;\n if (!GetLowLevelStats(&amp;info;stats, dwLowLevelMask))\n  return FALSE;\n \/\/ Convert the LOWLEVELSTATS into a FOOINFO\n pinfo-&gt;dwInUse = stats.dwUnitSize * stats.dwUnitsInUse;\n pinfo-&gt;dwAvailable = stats.dwUnitSize * stats.dwUnitsAvailable;\n pinfo-&gt;dwRequested = stats.dwUnitSize * stats.dwUnitsRequested;\n pinfo-&gt;dwDenied = stats.dwUnitSize *\n                   (stats.dwUnitsRequested - stats.dwUnitsGranted);\n return TRUE;\n}\n<\/pre>\n<p>\nNotice that if you ask for just <code>FOOINFO_DENIED<\/code>,\nyou still get the <code>dwRequested<\/code> as a side effect,\nsince computing the number of requests that were denied\nentails obtaining the total number of requests.\nOn the other hand, you also get garbage for <code>dwInUse<\/code>\nsince the call to <code>GetLowLevelStats<\/code> didn&#8217;t ask\nfor <code>LLSTATS_INUSE<\/code>, but the code that converts\nthe <code>LOWLEVELSTATS<\/code> to a <code>FOOINFO<\/code> doesn&#8217;t\nknow that and converts the uninitialized garbage.\nBut since you said that you didn&#8217;t care about the <code>dwInUse<\/code>\nmember, you shouldn&#8217;t be upset that it contains garbage.\n<\/p>\n<p>\nYou now know enough to answer\n<a HREF=\"http:\/\/groups.google.com\/groups?selm=EE986462-D73B-4E9B-969A-1C9E9F2D071E@microsoft.com\">\nthis person&#8217;s question<\/a>.\n<\/p>\n<p>\n(Note of course that I&#8217;m assuming we are not returning\nuninitialized garbage across a security boundary.)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>There are many situations where you pass a structure to a function, and the function fills in the structure with information you request. In some cases, the function always fills in the entire structure (example: GlobalMemoryStatus). In other cases, you tell the function which bits of information you care about, to save the function the [&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":[25],"class_list":["post-21983","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>There are many situations where you pass a structure to a function, and the function fills in the structure with information you request. In some cases, the function always fills in the entire structure (example: GlobalMemoryStatus). In other cases, you tell the function which bits of information you care about, to save the function the [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/21983","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=21983"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/21983\/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=21983"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=21983"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=21983"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}