May, 2009

  • The Old New Thing

    Lessons from the state police, like what to do when they pull you over


    NPR's Noah Adams rides along with the Idaho State Police and learns the answers to questions like what you should do when you are pulled over, and why the first thing the officer does is touch your car.

  • The Old New Thing

    Alternatives to using the #error directive to check whether the compiler even sees you


    In response to my description of how you can use the #error directive to check whether the compiler even sees you, some commenters proposed alternatives. I never claimed that my technique was the only one, just that it was another option available to you. Here are some other options.

    scott suggested merely typing asdasdasd into the header file and seeing if you get an error. This usually works, but it can be problematic if the code does not already compile. And of course it doesn't compile, because the reason why you're doing this investigation in the first place is that you can't get your code to compile and you're trying to figure out why. Consequently, it's not always clear whether any particular error was due to your asdasdasd or due to the fact that, well, your code doesn't compile. For example after adding your asdadsads to line 41 of file problem.h, you get the error Error: Semicolon expected at line 412 of file unrelated.h. Was that caused by your asdasdad? Doesn't seem that way, but it actually was, because the preprocessed output looked like this:

    int GlobalVariable;

    After your asdasdasd, all that was generated were a bunch of #defines, #ifs, #endifs, and #includes. None of them generate output, so the compiler proper doesn't see anything; the preprocessor ate it all. Finally, at unrelated.h line 412, a header file finally tried to do something other than just define a macro, and it's only then that the error is detected.

    But if you can pick the new error out of the error spew, then go for it. (There are also obscure cases where an extra asdasdasd doesn't introduce a new error.)

    Since the string #error is shorter than asdasdasd, and it works in more places, I just go with #error.

    Another suggestion came from Miguel Duarte who suggested generating the preprocessed file and studying it. That helps, but the preprocessor output tends to be huge, and, as I noted in the base article, #define directives don't show up, so it can be hard for you to find your place. I also noted in the base article that if you use Visual Studio's precompiled header files, the contents of the preprocessed output may not match what the compiler sees. In fact, that's the most common reason I've found for a line being ignored: You put the #include directive in a place that the preprocessor sees but which the compiler doesn't see because you violated one of the precompiled header consistency rules, usually the source file consistency rule.

  • The Old New Thing

    An unexpected application of the First Law of Thermodynamics


    This past winter, my furnace failed catastrophically. (The furnace repair person told me that when furnaces fail, it tends to be catastrophic failure.) It was a few days before everything was back in order, and the very day everything was working again, the furnace belonging to one of my relatives stopped working.

    This was an application of the First Law of Thermodynamics with which I had previously been unfamiliar.

    Fortunately, the repair on the second furnace was very simple and was done in just a few hours.

    After I informed my friends of my discovery of this law of the universe, one of them wrote, "Our furnace broke on Sunday. I can't help but feel like you're kind of responsible."

  • The Old New Thing

    I'm sorry, you don't have permission to know where this shortcut file should show up in the Explorer window


    Commenter Gabe suggested that the shortcut file should contain a bit that indicates whether the target of the shortcut is a folder, so that shortcuts to folders can sort with real folders. "That would allow them to sort properly without doing any additional work beyond that required to see its icon." (Commenter Josh agreed that "The performance reason doesn't really apply here, since explorer is already looking at the target to get the icon," rejecting commenter AndyC's argument that performance may have been a concern.)

    Well, first of all, shortcuts do remember whether the target is a file or a folder, or at least whether it was a file or folder at the time the shortcut was created: IShellLink::GetIDList + IShellFolder::GetAttributesOf tells you this and more about the shortcut target.

    But saying that this isn't more work than what's necessary to see the icon misses a few points about file icons: First, you can't sort by icon, so the consequences of getting the wrong icon (or never getting the icon at all) are purely visual. What? Never getting the icon at all? Well, yes, if the file has been archived to tape, Explorer won't bother recalling the file just to get its icon and will instead just use its generic type icon, or if there is no generic type icon, a generic document icon. After all, you don't want viewing a folder in Explorer to recall all the files from tape. That sort of defeats the purpose of archiving the files to tape.

    Even if Explorer decides to get the icon, it performs that operation at low priority and in the background. By comparison, you don't want to decide where the item should appear in the list as a low priority background task. If you do, then you either show nothing until all the sort information is ready (in other words, show nothing for a very long time, possibly forever if the file has been archived to tape), or you show everything, but move items around as better information arrives. Neither is a particularly pleasant experience for the user.

    What's more, it means that where an item sorts depends on who asks. If you don't have read permission on the shortcut file, then you don't have enough permission to find out whether it's a shortcut to a folder or not, and then Explorer has to decide where "don't know" files go. Do they go with the non-folders by default? Do you create a third "don't know" category? No matter what you choose, the result is that the location of the file changes depending on who asks. "Hey, where did that shortcut file go? Oh, there it is. What's it doing over there? Computers are so hard to use."

    Commenter Leo Davidson noted that determining whether the target of a shortcut is a file or folder is cheap if the target is a local hard drive that is not spun down, but that's an awful lot of ifs. Does this mean that you sort shortcuts to local hard drives that are not spun down differently from shortcuts to network drives or shortcuts to drives that are spun down? Won't users find this confusing? "Hey, where did that shortcut file go? Oh, there it is. What's it doing over there? Why does this shortcut file show up half of the time in one location and half of the time in that other location? Computers are so hard to use."

    Now, even if it's a shortcut and the target is on a local hard drive that has not spun down, that still doesn't mean that you can determine whether or not it is a file or a folder: The target may no longer exist. The act of resolving a broken shortcut is deferred until shortcut is launched, a form of lazy evaluation which avoids having to undertake an expensive search operation until the result is actually needed. If you want to sort shortcuts based on the attributes of the target, you'd have to resolve all the broken shortcuts to see where the target moved to and whether it's a file or a folder.

    Now, you might decide that broken shortcuts are already broken, so who cares what happens? But there are scenarios where almost all shortcuts are broken and the user relies on the resolution process to fix them up. But you knew this already. If the Start menu profile roams from one machine to another, the shortcuts are all broken, but when the user decides to launch the shortcut, the resolution process patches them up so they launch the correct program; it just takes a little longer the first time.

    I suspect that when Leo Davidson runs the program which sorts shortcuts to folders along with the folders and includes the shortcut target in the column description with "no noticeable effect on performance", he doesn't try running it against a server halfway around the world with a 500ms ping time. If you have a folder with 100 shortcuts over a network with 500ms latency, it'll take you nearly a minute just to sort the items. It'll be even worse if you have a folder full of files which have been archived to tape. Maybe that scenario isn't important to him, but it's important to a lot of people. In fact, one might say that the Explorer folks don't pay enough attention to these scenarios, because at every release of Windows, you can count on those people submitting streams of complaints that the most recent version of Explorer sucks even more on their international corporate network, and then the Explorer team has to do a little redesign work to get things to suck less.

  • The Old New Thing

    Before designing and implementing around an assumption, it helps to check that your assumption is true


    When your component depends on another component in the project, and that other component is missing features you need, you have a few ways of resolving the situation. Most people would recommend working with the people responsible for the other component during the project planning phase and coming to some sort of understanding about what you require from them and when they might be able to provide it, if at all.

    And then there's this approach. This imaginary email conversation takes place about halfway through a project:

    From: David Doe

    Hello, widget team. I'm David Doe, from the doodad team.

    Do widgets support cross-domain deserialization? If not, are there any plans to support it?

    A reply quickly arrives from the head of the widget team, answering both of the questions.

    From: Wendy Wilson

    No, widgets do not currently support that feature, and there are no plans to add it.

    The doodad team becomes a bit more concerned.

    From: David Doe

    This is really important to us. Doodads need to be able to deserialize widgets across domains, and we need to know when that support will be implemented.

    Like the sign says, Lack of planning on your part does not constitute an emergency on my part.

  • The Old New Thing

    How to hide privacy violations in a privacy disclosure statement, part 2


    It seems that nearly every privacy statement somebody sends me doesn't actually protect my privacy. They start out saying all sorts of great things, like

    Company X is committed to maintaining the privacy of its customers.

    After the section listing what information they collect, there's the section describing who they will disclose it to.

    We do not share non-public personal information with outside parties except as permitted by law...

    Oh, gee, thanks. Your policy is not to do anything illegal. And you need a privacy statement for this?

    Actually, it's worse, The full sentence goes like this:

    We do not share non-public personal information with outside parties except as permitted by law or as is necessary to service customer accounts.

    Notice the "or" rather than the "and". That means that they reserve the right to violate the law if it is necessary to provide service to a customer.

    And then, if they haven't already promised to protect nothing, they throw this in:

    Additionally, except as prohibited by law, we may disclose non-public personal information to companies that perform marketing services on our behalf or to other institutions with whom we have joint marketing agreements.

    Translation: We will sell your personal information to other companies for marketing purposes to the maximum extent permitted by law.

    But that's okay, because they restate their commitment to privacy in a final italicized paragraph.

    Protecting the confidentiality of your non-public personal information remains a priority for us, and is one way in which we respond to the trust you have placed in our organization.

    Because if you put it in italics, you really really mean it. Even if the other stuff contradicts it.

  • The Old New Thing

    What do you call a gadget that is used for debugging which looks at the properties of other gadgets?


    Why, the Inspector Gadget, of course.

    Computer geeks think they're so clever.

  • The Old New Thing

    The latest installment of Wallace and Gromit coming to Seattle


    The Seattle International Film Festival is under way, and you get only one chance to see Wallace and Gromit: A Matter of Loaf and Death, featuring our favorite inventor/cheese-aficionado and his trusty sidekick on their latest animated adventure.

    Be there on Saturday morning, but please leave the Stinking Bishop at home.

  • The Old New Thing

    Why can't you change the alignment of an edit control after it has been created?


    Commenter Kevin Eshbach asks why you cannot programatically change the text centering style of an edit control after the control has been created.

    The edit control is one of the original window manager controls, so it comes with a lot of history. First thing to note is that the WM_STYLECHANGED message did not exist until Windows 95. The edit control predates Windows 95 by over a decade, so the short answer is "It can't respond to the change in styles because it doesn't even know that you changed them!"

    Back in the old days, the only time a control was informed of its styles was in the CREATESTRUCT passed as parameters to the WM_CREATE and WM_NCCREATE messages. Consequently, most controls back in those days cached their styles in member variables so that they wouldn't have to call GetWindowLong(GWL_STYLE) all the time. This was back in the days of 4.77MHz CPUs, and a call to fetch the style of a window was quite a bit bigger and slower than just reading it out of your local data segment.

    Even if you decided "Forget it, I won't bother with a cache; I'll just call GetWindowLong(GWL_STYLE) to read the style each time I need it", you open yourself up to a new problem: What if the style changes? A change in the style means that the characters in the edit box need to have their positions recalculated and the text redrawn. This is obviously not something you want to do at every single message (redrawing at every message is probably not a great idea), so you still need to cache the old style so you can avoid recalculating stuff that hasn't changed.

    Even if you say, "Okay, fine, then instead of changing the style with SetWindowLong(GWL_STYLE), let's say that if you want to change the style of an edit control, you have to use a new message, something like EM_CHANGESTYLE." That way, the edit control knows when its styles have changed and doesn't have to keep polling for them. When it gets this message, it updates the styles and recalculates all its internal state based on the new style.

    Okay, sure it could've done this, but that's code that has to be written and tested, for an extremely rare usage pattern. I mean, what is the scenario where somebody needs to change an edit control from left-aligned to right-aligned on the fly? You could count all the Windows 1.0 applications on your fingers and toes (note: exaggeration), and they just decided in the dialog template which way the text should be aligned. It was determined not just at creation time; it was determined at compile time.

    If you want to change an edit control's alignment on the fly, you can just destroy the old one and create a new one in its place with the same text.

  • The Old New Thing

    Chicken chicken chicken chicken


    Chicken chicken chicken chicken. [pdf]

    Chicken: Chicken chicken chicken.

Page 1 of 3 (29 items) 123