<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Even if a function doesn't do anything, you still have to call it if the documentation says so, because it might do something tomorrow</title><link>http://blogs.msdn.com/b/oldnewthing/archive/2008/09/25/8965129.aspx</link><description>The sad history of GetEnvironmentStrings().</description><dc:language>en-US</dc:language><generator>Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><item><title>re: Even if a function doesn't do anything, you still have to call it if the documentation says so, because it might do something tomorrow</title><link>http://blogs.msdn.com/b/oldnewthing/archive/2008/09/25/8965129.aspx#8972068</link><pubDate>Wed, 01 Oct 2008 22:13:20 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8972068</guid><dc:creator>640k</dc:creator><description>&lt;p&gt;Windows APIs has a lot of magic, can't be sure about anything.&lt;/p&gt;
&lt;p&gt;C functions which returns buffers are always tricky, easy to get it wrong both when implementing the api code and the application code.&lt;/p&gt;
&lt;p&gt;&amp;quot;const&amp;quot; keyword doesn't compile to anything, and isn't enforced when executing.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8972068" width="1" height="1"&gt;</description></item><item><title>re: Even if a function doesn't do anything, you still have to call it if the documentation says so, because it might do something tomorrow</title><link>http://blogs.msdn.com/b/oldnewthing/archive/2008/09/25/8965129.aspx#8969741</link><pubDate>Tue, 30 Sep 2008 05:17:06 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8969741</guid><dc:creator>James</dc:creator><description>&lt;p&gt;You don't need to read every line of the manual in this case.&lt;/p&gt;
&lt;p&gt;You have a function that returns a pointer (and a non-const one, no less). &amp;nbsp;People with common sense should ask, &amp;quot;who owns the pointee, and if it's the caller's responsibility to free it, how does the caller do so?&amp;quot;. &amp;nbsp;You don't even need to look at the manual first to know to ask these questions; they're implied by the function signature.&lt;/p&gt;
&lt;p&gt;A quick scan through the documentation should answer those questions.&lt;/p&gt;
&lt;p&gt;But sadly, I admit that common sense is not nearly as common as it ought to be.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8969741" width="1" height="1"&gt;</description></item><item><title>re: Even if a function doesn't do anything, you still have to call it if the documentation says so, because it might do something tomorrow</title><link>http://blogs.msdn.com/b/oldnewthing/archive/2008/09/25/8965129.aspx#8969440</link><pubDate>Mon, 29 Sep 2008 23:21:08 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8969440</guid><dc:creator>M1EK</dc:creator><description>&lt;P&gt;Ding ding ding for Matt Craighead's answer.&lt;/P&gt;
&lt;P&gt;Also, you don't need a time machine to identify that more than one party was to blame here. That doesn't change the solution now, but it does help us possibly avoid future problems of this type.&lt;/P&gt;
&lt;P&gt;A programming API that requires that every programmer have read every single line of the manual to avoid dying in flames is not a good API. There was a time I felt differently, of course. I got better.&lt;/P&gt;
&lt;DIV class=post&gt;[&lt;I&gt;You didn't have to read every single line of the manual. The information was right there in the documentation for GetEnvironmentStrings: "When the block returned by GetEnvironmentStrings is no longer needed, it should be freed by calling the FreeEnvironmentStrings function." And besides, when you call a function that returns some sort of resource, don't you naturally want to know "What do I do when I'm done with it?" -Raymond&lt;/I&gt;]&lt;/DIV&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8969440" width="1" height="1"&gt;</description></item><item><title>re: Even if a function doesn't do anything, you still have to call it if the documentation says so, because it might do something tomorrow</title><link>http://blogs.msdn.com/b/oldnewthing/archive/2008/09/25/8965129.aspx#8969371</link><pubDate>Mon, 29 Sep 2008 22:29:52 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8969371</guid><dc:creator>Matt Craighead</dc:creator><description>&lt;p&gt;If we really want to criticize the API design in any detail, I would also point out that getting the entire environment block is very rarely what you want. &amp;nbsp;Nor is the format of the environment block very application-friendly to parse, and there are plenty of opportunities for bugs there, too (can you say case sensitivity problems?).&lt;/p&gt;
&lt;p&gt;I would rather keep the format and order of the environment block hidden (so you're free to change it -- what if you wanted to change it to a hash table or binary tree to increase performance?), and only provide getenv/setenv APIs. &amp;nbsp;There is then the question of providing an environment block at process creation, but there, I expect you generally either want to (A) inherit everything or (B) build a new environment from scratch, selectively inheriting using getenv() if necessary.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8969371" width="1" height="1"&gt;</description></item><item><title>re: Even if a function doesn't do anything, you still have to call it if the documentation says so, because it might do something tomorrow</title><link>http://blogs.msdn.com/b/oldnewthing/archive/2008/09/25/8965129.aspx#8968773</link><pubDate>Mon, 29 Sep 2008 15:20:18 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8968773</guid><dc:creator>fdiv</dc:creator><description>&lt;p&gt;I never disassemble the Windows code to see what an API does and not just because the EULA forbids it. Most of the time either Raymond explains it, or I look at what Wine does and that often explains things.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8968773" width="1" height="1"&gt;</description></item><item><title>re: Even if a function doesn't do anything, you still have to call it if the documentation says so, because it might do something tomorrow</title><link>http://blogs.msdn.com/b/oldnewthing/archive/2008/09/25/8965129.aspx#8967454</link><pubDate>Sat, 27 Sep 2008 11:51:52 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8967454</guid><dc:creator>SuperKoko</dc:creator><description>&lt;p&gt;[Okay, you have a time machine. What do you do? Do you have the cleanup function do some pointless busy work just so it does &amp;quot;something&amp;quot;? -Raymond]&lt;/p&gt;
&lt;p&gt;I don't think the implementation is flawed, but if I had a time machine I might take a very defensive approach: Counting resource references. Incrementing a process-wide counter when GetEnvironmentStrings is called and decreasing it when FreeEnvironmentStrings is called. If the count, when a process terminates or exit, is non-zero, this event would be logged.&lt;/p&gt;
&lt;p&gt;However, its limit are obvious:&lt;/p&gt;
&lt;p&gt;1) It doesn't prevent application from calling FreeEnvironmentStrings on the wrong pointer.&lt;/p&gt;
&lt;p&gt;Adding testing logic is possible, but would necessarily GetEnvironmentStrings to copy the string.&lt;/p&gt;
&lt;p&gt;(An instance ordinal would be added in the bytes preceding the string... People would obviously mess with it...)&lt;/p&gt;
&lt;p&gt;2) Programmers would ignore the logs.&lt;/p&gt;
&lt;p&gt;3) It is making the release version of Windows look like a debug version. Just because bad programmers don't use debugging tools, end users would suffer from performances of debugging tools.&lt;/p&gt;
&lt;p&gt;@M1EK: So, are you telling us that the average programmer doesn't read the manual but disassemble the Windows code? I cannot believe that!&lt;/p&gt;
&lt;p&gt;I would rather expect the bad programmer not to care about resource leaks as far as the memory leaks don't make his program crash in an &amp;quot;out of memory&amp;quot; condition afer 10 minutes, which is not likely to happen with little-used resources such as environment blocks and kernel handles.&lt;/p&gt;
&lt;p&gt;&amp;quot;what would you have done at the time you created your first win32 window?&amp;quot;&lt;/p&gt;
&lt;p&gt;I remember very well. I carefully read the SDK documentation and took an extremely defensive approach everywhere I wasn't sure... Of course, as I usually do, I freed resources in the reverse order of their allocation. Later, as I better knew the documentation, I relaxed my programming technique.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8967454" width="1" height="1"&gt;</description></item><item><title>re: Even if a function doesn't do anything, you still have to call it if the documentation says so, because it might do something tomorrow</title><link>http://blogs.msdn.com/b/oldnewthing/archive/2008/09/25/8965129.aspx#8967189</link><pubDate>Sat, 27 Sep 2008 02:25:58 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8967189</guid><dc:creator>_</dc:creator><description>&lt;p&gt;what would you have done at the time you created your first win32 window? i believe that you are now capable of using win32 correctly but only because you have gone through every misery unmanaged code has to offer at least once ;-) unfortunately many programmers are, after 10 years of experience, still at the entry level.&lt;/p&gt;
&lt;p&gt;an api can be designed to help you and it can be designed without consciousness of usability. GetEnvironmentStrings one is of the latter (although the usability problem is only minor. there are other examples as well).&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8967189" width="1" height="1"&gt;</description></item><item><title>re: Even if a function doesn't do anything, you still have to call it if the documentation says so, because it might do something tomorrow</title><link>http://blogs.msdn.com/b/oldnewthing/archive/2008/09/25/8965129.aspx#8967155</link><pubDate>Sat, 27 Sep 2008 02:01:59 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8967155</guid><dc:creator>Duke of New York</dc:creator><description>&lt;p&gt;The name of the API is &amp;quot;GetEnvironmentStrings.&amp;quot; Its job, believe it or not, is to get environment strings and then let the application move on-- not to anticipate whether you need a copy, how many, for how long, from which allocators, etc., etc. All of those are things the application can manage for itself, using other APIs, or no APIs.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8967155" width="1" height="1"&gt;</description></item><item><title>re: Even if a function doesn't do anything, you still have to call it if the documentation says so, because it might do something tomorrow</title><link>http://blogs.msdn.com/b/oldnewthing/archive/2008/09/25/8965129.aspx#8967132</link><pubDate>Sat, 27 Sep 2008 01:50:22 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8967132</guid><dc:creator>_</dc:creator><description>&lt;p&gt;&amp;quot;Then the app is ignoring the part of the documentation that says&amp;quot;&lt;/p&gt;
&lt;p&gt;this is constantly happening. after all, this blog is partially about the phenomenon of bad code. as a systems designer you cannot ignore this. i even have to think about it when coworkers are using my code!&lt;/p&gt;
&lt;p&gt;&amp;quot;If you need a copy for applications-specific reasons, make a copy. It's not the operating system's job to write your application for you.&amp;quot;&lt;/p&gt;
&lt;p&gt;of course it is! the operating system provides services to you in order to alleviate the need for implementing them yourself. the reason for choosing a development platform is that one platform might reduce your work more than the other.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8967132" width="1" height="1"&gt;</description></item><item><title>re: Even if a function doesn't do anything, you still have to call it if the documentation says so, because it might do something tomorrow</title><link>http://blogs.msdn.com/b/oldnewthing/archive/2008/09/25/8965129.aspx#8967130</link><pubDate>Sat, 27 Sep 2008 01:44:49 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8967130</guid><dc:creator>Duke of New York</dc:creator><description>&lt;p&gt;&amp;quot;what if the app decides to use the returned buffer as some kind of working memory an does string operations in it?&amp;quot;&lt;/p&gt;
&lt;p&gt;Then the app is ignoring the part of the documentation that says:&lt;/p&gt;
&lt;p&gt;&amp;quot;Treat this memory as read-only&amp;quot;&lt;/p&gt;
&lt;p&gt;Aside from that, the end-to-end principle applies. If you need a copy for applications-specific reasons, make a copy. It's not the operating system's job to write your application for you.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8967130" width="1" height="1"&gt;</description></item></channel></rss>