• The Old New Thing

    A very brief anecdote about Windows 3.0

    • 14 Comments

    In an earlier comment, Larry Osterman described why Windows 3.0 was such a runaway success. He got a little of the timeline wrong, so I'll correct it here.

    Windows 2.0 did support protected mode. And it was Windows/386, which came out before Windows 3.0, which first used the new virtual-x86 mode of the 80386 processor to support pre-emptively multitasked DOS boxes. The old Windows 2.0 program was renamed "Windows/286" to keep the names in sync.

    The three modes of Windows then became "real mode" (Windows 1.0 style), "standard mode" (Windows/286 style) and "enhanced mode" (Windows/386 style). Amazingly, even though the way the operating system used the processor was radically different in each of the three modes, a program written for "real mode" successfully ran without change in the other two modes. You could write a single program that ran on all three operating systems.

    And then Windows 3.0 came out and the world changed. Sales were through the roof. I remember that some major software reseller (Egghead?) was so pleased with the success of Windows 3.0 that it bought bought every Microsoft employee a Dove ice cream bar. (Even the employees like me who were working on OS/2.) I was sitting in my office and some people came in with a big box of ice cream bars and they handed me one. "This is from Egghead. Thank you for making Windows 3.0 a success," they said.

    It was a strange feeling, getting a thank-you for something you not only didn't work on, but something which totally destroyed the project you were working on!

    [Raymond is currently on vacation; this message was pre-recorded.]

  • The Old New Thing

    Reference counting is hard.

    • 48 Comments

    One of the big advantages of managed code is that you don't have to worry about managing object lifetimes. Here's an example of some unmanaged code that tries to manage reference counts and doesn't quite get it right. Even a seemingly-simple function has a reference-counting bug.

    template <class T>
    T *SetObject(T **ppt, T *ptNew)
    {
     if (*ppt) (*ppt)->Release(); // Out with the old
     *ppt = ptNew; // In with the new
     if (ptNew) (ptNew)->AddRef();
     return ptNew;
    }
    

    The point of this function is to take a (pointer to) a variable that points to one object and replace it with a pointer to another object. This is a function that sits at the bottom of many "smart pointer" classes. Here's an example use:

    template <class T>
    class SmartPointer {
    public:
     SmartPointer(T* p = NULL)
       : m_p(NULL) { *this = p; }
     ~SmartPointer() { *this = NULL; }
     T* operator=(T* p)
       { return SetObject(&m_p, p); }
     operator T*() { return m_p; }
     T** operator&() { return &m_p; }
    private:
     T* m_p;
    };
    
    void Sample(IStream *pstm)
    {
      SmartPointer<IStream> spstm(pstm);
      SmartPointer<IStream> spstmT;
      if (SUCCEEDED(GetBetterStream(&spstmT))) {
       spstm = spstmT;
      }
      ...
    }
    

    Oh why am I explaining this? You know how smart pointers work.

    Okay, so the question is, what's the bug here?

    Stop reading here and don't read ahead until you've figured it out or you're stumped or you're just too lazy to think about it.


    The bug is that the old object is Release()d before the new object is AddRef()'d. Consider:

      SmartPointer<IStream> spstm;
      CreateStream(&spstm);
      spstm = spstm;
    

    This assignment statement looks harmless (albeit wasteful). But is it?

    The "smart pointer" is constructed with NULL, then the CreateStream creates a stream and assigns it to the "smart pointer". The stream's reference count is now one. Now the assignment statement is executed, which turns into

     SetObject(&spstm.m_p, spstm.m_p);
    

    Inside the SetObject function, ppt points tp spstm.m_p, and pptNew equals the original value of spstm.m_p.

    The first thing that SetObject does is release the old pointer, which now drops the reference count of the stream to zero. This destroys the stream object. Then the ptNew parameter (which now points to a freed object) is assigned to spstm.m_p, and finally the ptNew pointer (which still points to a freed object) is AddRef()d. Oops, we're invoking a method on an object that has been freed; no good can come of that.

    If you're lucky, the AddRef() call crashes brilliantly so you can debug the crash and see your error. If you're not lucky (and you're usually not lucky), the AddRef() call interprets the freed memory as if it were still valid and increments a reference count somewhere inside that block of memory. Congratulations, you've now corrupted memory. If that's not enough to induce a crash (at some unspecified point in the future), when the "smart pointer" goes out of scope or otherwise changes its referent, the invalid m_p pointer will be Release()d, corrupting memory yet another time.

    This is why "smart pointer" assignment functions must AddRef() the incoming pointer before Release()ing the old pointer.

    template <class T>
    T *SetObject(T **ppt, T *ptNew)
    {
     if (ptNew) (ptNew)->AddRef();
     if (*ppt) (*ppt)->Release();
     *ppt = ptNew;
     return ptNew;
    }
    

    If you look at the source code for the ATL function AtlComPtrAssign, you can see that it exactly matches the above (corrected) function.

    [Raymond is currently on vacation; this message was pre-recorded.]

  • The Old New Thing

    Why a really large dictionary is not a good thing

    • 42 Comments

    Sometimes you'll see somebody brag about how many words are in their spell-checking dictionary. It turns out that having too many words in a spell checker's dictionary is worse than having too few.

    Suppose you had a spell checker whose dictionary contained every word in the Oxford English Dictionary. Then you hand it this sentence:

    Therf werre eyght bokes.

    That sentence would pass with flying colors, because all of the words in the above sentence are valid English words, though most people would be hard-pressed to provide definitions.

    The English language has so many words that if you included them all, then common typographical errors would often match (by coincidence) a valid English word and therefore not be detected by the spell checker. Which would go against the whole point of a spell checker: To catch spelling errors.

    So be glad that your spell checker doesn't have the largest dictionary possible. If it did, it would end up doing a worse job.

    After I wrote this article, I found a nice discussion of the subject of spell check dictionary size on the Wintertree Software web site.

    [Raymond is currently on vacation; this message was pre-recorded.]

  • The Old New Thing

    The martial arts logon picture

    • 20 Comments

    Along the lines of Windows as Rorschach test, here's an example of someone attributing malicious behavior to randomness.

    Among the logon pictures that come with Windows XP is a martial arts kick. I remember one bug we got that went something like this:

    "Windows XP is racist. It put a picture of a kung fu fighter next to my name - just because my name is Chinese. This is an insult!"

    The initial user picture is chosen at random from among the pictures in the "%ALLUSERSPROFILE%\Application Data\Microsoft\User Account Pictures\Default Pictures" directory. It just so happened that the random number generator picked the martial arts kick out of the 21 available pictures.

    I'm also frustrated by people who find quirks in spellcheckers and attribute malicious intent to them. You know what I'm talking about. "Go to Word and type in <some name that's not in the dictionary> and tell it to spellcheck. Word will flag the word and recommend <some other word that is somehow opposite to the first word in meaning> instead. This is an insult! Microsoft intentionally taught the spellchecker to suggest <that word> when you type <this word>. This is clear proof of <some bad thing>."

    More on spell checking tomorrow.

    [Raymond is currently on vacation; this message was pre-recorded.]

  • The Old New Thing

    The look of Luna

    • 76 Comments

    Luna was the code name for the Windows XP "look". The designers did a lot of research (and got off to a lot of false starts, as you might expect) before they came to the design they ultimately settled upon.

    During the Luna studies, that people's reaction to Luna was often, "Wow this would be a great UI for X," where X was "my dad" or "my employees" or "my daughter". People didn't look at it as the UI for themselves; rather, they thought it was a great UI for somebody else.

    It was sometimes quite amusing to read the feedback. One person would write, "I can see how this UI would work great in a business environment, but it wouldn't work on a home computer." and the very next person would write "I can see how this UI would work great on a home computer, but it wouldn't work in a business environment."

    (And interestingly, even though armchair usability experts claim that the "dumbed-down UI" is a hindrance, our studies showed that people were actually more productive with the so-called "dumb" UI. Armchair usability experts also claim that the Luna look is "too silly for serious business purposes", but in reality it tested very well on the "looks professional" scale.)

    Aero is the code name for the Longhorn "look". With Aero, the designers have turned an important corner. Now, when they show Aero to people, the reaction is, "Wow, this would be a great UI for me to use."

    People want Luna for others, but they want Aero for themselves.

    [Raymond is currently on vacation; this message was pre-recorded.]

  • The Old New Thing

    When temperance backfires

    • 9 Comments
    [South Carolina is] the only state in the nation requiring bars to serve all hard liquor in minibottles. The minibottle's place behind the bar is even enshrined in the state's constitution.

    Mini-bottles are those cute little single-serving bottles you see on airplanes and in hotel refrigerators.

    The law was originally passed under pressure from the temperance movement who opposed "free pour" because it created the opportunity for bartenders to "sweeten" a drink. By requiring the liquor to come from a fixed-sized bottle, portion sizes could be kept under control.

    This worked great for a while. But then social pressures shifted and economics started happening. Across the country, the typical size of an alcoholic beverage started shrinking. But South Carolina's drink size stayed the same, because the size was mandated by law. The result: absurdly huge drinks, like the Long Island Iced Tea that comes in a pitcher. South Carolina ended up with the stiffest drinks in the country, exactly the opposite of what the original drafters intended!

    The very people who helped West pass the minibottle law as a way to limit consumption -- the teetotalers and religious conservatives -- are now helping Hayes's bid to abolish the law.

    The effort to repeal the law has been going on for many years, but somehow it always falls short. Maybe this year...

    [Raymond is currently on vacation; this message was pre-recorded.]

  • The Old New Thing

    Where did my Task Manager tabs and buttons go?

    • 33 Comments

    Ah, welcome to "Tiny Footprint Mode".

    This mode exists for the ultrageeks who want to put a tiny little CPU meter in the corner of the screen. To go back to normal mode, just double-click a blank space in the border.

    This is one of those geek features that has created more problems than it solved. Sure, the geeks get their cute little CPU meter in the corner, but for each geek that does this, there are thousands of normal users who accidentally go into Tiny mode and can't figure out how to get back.

    [Raymond is currently on vacation; this message was pre-recorded.]

  • The Old New Thing

    "Special skills" draft on the drawing board

    • 5 Comments

    The [U.S.] government is taking the first steps toward a targeted military draft of Americans with special skills in computers and foreign languages.

    Apparently, there is already a special system to draft "health care personnel", whatever that means.

    Can you imagine the havoc that could be wrought by disgruntled programmers forced to write code for the government?

    So all I have to do now is volunteer at the local hospital and I'll have hit the conscription jackpot.

    [Raymond is currently on vacation; this message was pre-recorded.]

  • The Old New Thing

    It's embarrassing how little Swedish you need to know

    • 27 Comments

    Because everybody here speaks English. Perfectly.

    Sometimes they'll speak English to me even before I say anything. (My comparative silence probably gives me away as a non-native.) Other times they'll notice that I'm speaking with a bad accent and switch to English. Some humor me by speaking Swedish until I finally break down and ask (in English), "I'm sorry, could you say that again?" because they're speaking Swedish too fast for me to keep up.

    When dealing with non-Swedes, the default language is English. Not because people from English-speaking countries are so prevalent, but because English is everybody's second language. If a German and a Russian meet, they'll talk in English.

    In other language news: On the flight out of Seattle, a variety of newspapers were available and I grabbed what turned out to be a Norwegian paper by mistake. But it turns out that if you know Swedish, you can read a Norwegian paper anyway; it's no big deal.

    Yesterday, one of Jonathan's corridormates listened patiently as I said "sju" ("seven") over and over again until I could get the sj-sound right. It went like this:

    Me: "Sju."

    Peter: "Nope."

    Me: "Sju."

    Peter: "Nope."

    Me: "Sju."

    Peter: "Nope."

    Me: "Sju."

    Peter: "Nope."

    Me: "Sju."

    Peter: "Nope."

    Me: "Sju."

    Peter: "Nope."

    Me: "Sju."

    Peter: "Nope."

    Me: "I give up."

    Peter: "That's okay."

  • The Old New Thing

    Why Ctrl+Alt shouldn't be used as a shortcut modifier

    • 22 Comments

    You may have noticed that Windows doesn't use Ctrl+Alt as a keyboard shortcut anywhere. (Or at least it shouldn't.) If a chorded modifier is needed, it's usually Ctrl+Shift.

    That's because Ctrl+Alt has special meaning on many keyboards. The combination Ctrl+Alt is also known as AltGr, and it acts as an alternate shift key. For example, consider the German keyboard layout. Notice that there are three keyboard shift states (Normal, Shift, and AltGr), whereas on U.S. keyboards there are only two (Normal and Shift). For example, to type the @ character on a German keyboard, you would type AltGr+Q = Ctrl+Alt+Q. (Some languages, like Swedish, have a fourth state: Shift+AltGr. And then of course, there's the Japanese keyboard...)

    Most international keyboards remap the right-hand Alt key to act as AltGr, so instead of the finger-contorting Ctrl+Alt+Q, you can usually type RAlt+Q.

    (For reference, here are diagrams of several other keyboard layouts, courtesy of my bubble-blowing friend, Nadine Kano.)

    Sometimes a program accidentally uses Ctrl+Alt as a shortcut modifier and they get bug reports like, "Every time I type the letter 'đ', the program thinks I want to start a mailmerge."

    [Raymond is currently on vacation; this message was pre-recorded.]

Page 396 of 427 (4,268 items) «394395396397398»