April, 2008

  • The Old New Thing

    Raymond misreads newspaper headlines, episode 2


    I have a strange tendency to misread newspaper headlines. This week, I read the headline Rogan Sets 200 Back World Record, and I thought, "There's a world record for running 200 meters backward?"

    Well, actually there is, but this article was actually about the 200 meter backstroke (swimming).

    Once I figured that out, I was not confused by the next headline: Lochte Sets 100 IM World Record.

  • The Old New Thing

    Raymond's reading list: The Mythical Man-Month, The Design of Everyday Things, and Systemantics


    The first two of these books are probably on everybody else's reading list, but I'm going to mention them anyway since I consider them required reading for managers and designers.

    The Mythical Man-Month is over 30 years old, but the lessons contained therein are as true now as they were back in 1975, such as what is now known as Brooks' law: Adding manpower to a late software product makes it later.

    I much preferred the original title for The Design of Everyday Things, namely, The Psychology of Everyday Things, but I'm told that booksellers ended up mistakenly filing the book in the psychology section. Once you've read this book, you will never look at a door the same way again. And you'll understand the inside joke when I say, "I bet it won an award."

    The third book is the less well-known Systemantics: How Systems Work and Especially How They Fail. The book was originally published in 1978, then reissued under the slightly less catchy title, Systemantics: The Underground Text of Systems Lore, and re-reissued under the completely soul-sucking title The Systems Bible. I reject all the retitling and continue to refer to the book as Systemantics.

    Systemantics is very much like The Mythical Man-Month, but with a lot more attitude. The most important lessons I learned are a reinterpretation of Le Chatelier's Principle for complex systems ("Every complex system resists its proper functioning") and the Fundamental Failure-Mode Theorem ("Every complex system is operating in an error mode").

    You've all experienced the Fundamental Failure-Mode Theorem: You're investigating a problem and along the way you find some function that never worked. A cache has a bug that results in cache misses when there should be hits. A request for an object that should be there somehow always fails. And yet the system still worked in spite of these errors. Eventually you trace the problem to a recent change that exposed all of the other bugs. Those bugs were always there, but the system kept on working because there was enough redundancy that one component was able to compensate for the failure of another component. Sometimes this chain of errors and compensation continues for several cycles, until finally the last protective layer fails and the underlying errors are exposed.

    That's why I'm skeptical of people who look at some catastrophic failure of a complex system and say, "Wow, the odds of this happening are astronomical. Five different safety systems had to fail simultaneously!" What they don't realize is that one or two of those systems are failing all the time, and it's up to the other three systems to prevent the failure from turning into a disaster. You never see a news story that says "A gas refinery did not explode today because simultaneous failures in the first, second, fourth, and fifth safety systems did not lead to a disaster thanks to a correctly-functioning third system." The role of the failure and the savior may change over time, until eventually all of the systems choose to have a bad day all on the same day, and something goes boom.

  • The Old New Thing

    I know you can't provide tax advice, but I'm just looking for tax advice


    One of my friends works at the help desk of a university library, and a while back she told two stories of people who asked for help without first engaging the part of the brain responsible for logic and reason.

  • The Old New Thing

    Email tip: Nostalgia is not a question


    This is another special case of Don't forget to ask your question, indeed an even more extreme case of Making some statements and asking for advice isn't a question.

    I remember in version X, we used to be able to accomplish Task Q by clicking on W and then selecting X. Now you have to click on Y and select Z.

    Nostalgia is not a question, and it isn't actionable.

    What is your question? Do you want an explanation of why it changed? Are you looking for a way to change it back? Are you just reminiscing? Or maybe you're congratulating the design team for simplifying the task?

  • The Old New Thing

    Follow-up: That shopautodotca seocontest online contest


    So I didn't win the shopautodotca seocontest search engine optimization contest, so I decided to check on how the actual winners were faring. After all, one of the winners was supposed to become the company's SEO manager.

    The top prize winners in the Google category and in the MSN category have both complained that they haven't received their prizes yet and have threatened to file a fraud claim. (Dead link to forum.) The top prize winner in the Yahoo category hasn't said anything one way or the other.

    Meanwhile, the forum hosted by the contest organizers was emptied of all messages, rendering it a breeding ground for message board spam. (It was subsequently taken down late last year.)

    I suspect that's the last I'll hear of this contest; I don't anticipate any resolution to emerge.

  • The Old New Thing

    Why doesn't Explorer let you create a file whose name begins with a dot?


    Rolf Viehmann asks why Explorer doesn't let you create a file whose name begins with a dot.

    Such files are considered to have an extension but no name. If the extension is known and the user has chosen to hide known extensions, the resulting file would have no name at all!

    If you really want to create a file with a leading dot in its name, you are free to do so. You can do it from the command line or use your favorite file management tool. And then you can watch the file show up with no name and then observe the confusion that ensues. Maybe you're lucky and don't run any programs that freak out when a file has no name. If so, then more power to you.

    If it really bugs you that you can't do it from Explorer, you are free to write your own shell extension to do "Rename this file, and if I'm going to shoot myself in the foot, then let me."

  • The Old New Thing

    We can't cut that; it's our last feature


    Many years ago, I was asked to help a customer with a problem they were having. I don't remember the details, and they aren't important to the story anyway, but as I was investigating one of their crashes, I started to wonder why they were even doing it.

    I expressed my concerns to the customer liaison. "Why are they writing this code in the first place? The performance will be terrible, and it'll never work exactly the way they want it to."

    The customer liaison confided, "Yeah, I thought the same thing. But this is a feature they're adding to the next version of their product. The product is so far behind schedule, they've been cutting features like mad to get back on track. But they can't cut this feature. It's the last one left!"

  • The Old New Thing

    The dead desktop computer: The good, the bad, and the ugly, but not in that order


    When last we left my dead desktop computer, it had fried its second video card, and I was considering whether I should get a third.

    I did indeed get a third video card, a cheap one since I knew that if the computer really did eat video cards, I'd have to feed it on a budget. I plugged it in, and...

    Computer still dead. Bad.

    Remove the video card, and the computer boots up.

    Okay, so the computer doesn't actually eat video cards. The problem is that the PCI Express slot is dead, for whatever reason, be it a fried component, a failing power supply, who knows.

    While I was back behind the computer, I noticed an unused plug: Yup, it was for VGA video output. I plugged in a VGA video cable, and, leaving the PCI Express video card unplugged, turned on the computer. Lo and behold, the computer started up and sent images out the VGA cable. Good.

    I didn't realize that the motherboard has an onboard video card. In the absence of a plug-in video card, the onboard video card takes over and pumps out video just fine. I don't use the computer for anything video-intensive, so a lame, underpowered video card is just fine by me.

    The problem is that the onboard video card has only VGA out, so I'm running an analog signal to my LCD monitor. Ugly.

    But at least it's a situation I can live with for now.

  • The Old New Thing

    Who defined my name first? Turnabout is fair play


    You're trying to compile your program and you're getting an error complaining that somebody already has a conflicting definition for a macro or some other name you're using.

    error: sample.cpp(35): conflicting definition of macro 'AWESOME'
    error: sample.cpp(92): conflicting definition of type 'AWESOME'

    If your compiler is helpful, it'll tell you where the previous definition was. But what if your compiler isn't quite so helpful? How can you find that conflicting definition?

    Turnabout is fair play.

    (I don't actually believe that turnabout is fair play, but it makes for a catchy title.)

    The problem is that you're the second definition and you want to find the first definition. So jump to the head of the line and become the new first definition. Compile the file with the -DAWESOME=@ command line switch. This tells the compiler to act as if the line #define AWESOME @ were at the top of the file.

    When the offending line is reached, the line that defines the AWESOME macro or declares a type named AWESOME or otherwise uses the word AWESOME, you'll get a compiler error. If it's a conflicting macro definition, you'll get something like

    error: header.h(10): conflicting definition of macro 'AWESOME'

    when the first definition is reached. With your addition of the -D, it's now the second definition, and therefore its definition conflicts with yours. Similarly, if it's a conflicting type name, you'll get something like

    error: header.h(30): illegal character @ in source file

    when the conflicting type definition is reached. This time, instead of a conflicting macro definition, you created a syntax error.

    On the other hand, if somebody #undefs your symbol before redefining it, then the -D trick won't work.

    As I noted, if your compiler is friendly and helpful, you won't need to use this tip, but sometimes you you have to make do with what you've got.

  • The Old New Thing

    Use the #error directive to check whether the compiler even sees you


    You may find yourself in a twisty maze of #ifdefs. Or you may be wondering why your macros aren't working.

    I have these lines in my header file:

    #define MM_BUSY     0x0001
    #define MM_IDLE     0x0002

    but when I try to use them, I get errors.

    sample.cpp(23): error C2065: 'MM_BUSY': undeclared identifier
    sample.cpp(40): error C2065: 'MM_IDLE': undeclared identifier

    Any idea why this is happening?

    First, make sure the compiler even sees you. Notice that for macros, generating a preprocessed file doesn't accomplish anything since #defines don't show up in the preprocessor output. (They are preprocessor input.) What I do is use the #error directive. Add it to the header file and recompile.

    #define MM_BUSY     0x0001
    #define MM_IDLE     0x0002
    #error Did we get here?

    If you get

    sample.h(80) : error C1189: #error :  Did we get here?

    then you know that the line is indeed being compiled and that somebody after you is doing an #undef MM_BUSY. If not, then you get to investigate why the lines in the header file are being ignored. For example, they might be hidden by an #ifdef, or (if you're using Visual Studio with precompiled headers), your #include directive might be ignored due to an overriding precompiled header directive. You can scatter #error directives into other parts of the header file (or other header files) to narrow down why your lines are being skipped.

Page 3 of 5 (41 items) 12345