April, 2004

  • The Old New Thing

    Extreme croquet


    This week, Only a Game covered the sport of Extreme Croquet.

    Still doesn't hold a candle to Extreme Ironing, though.

  • The Old New Thing

    Using the echo command to remember what you were doing.


    Sometimes you'll start typing a complex command line and then realize that you can't execute it now. Perhaps you're in the wrong directory or you forgot to map the drive. It would be a shame to hit ESC and lose that command line.

    What I do is edit the line to insert the word "echo" in front, then hit Enter. (Note: This doesn't work if you have command line redirection.)

    This prints the command to the screen, where it can be cut/pasted later. Even more, it enters the line into the command history, so a few uparrows will bring it back.

  • The Old New Thing

    $501 for 510g of peanut butter


    You can buy 510 grams of peanut butter for only $501.

    Of course, this is special peanut butter. It must be kept at -20°C. And it is not intended for human consumption.

    This is peanut butter from the National Institute of Standards and Technology intended for use by food analysis laboratories to calibrate their equipment. For example, standard peanut butter consists of 10.4% ± 0.2% saturated fat.

    (Link courtesy of Slate.)

  • The Old New Thing

    What is __purecall?


    Both C++ and C# have the concept of virtual functions. These are functions which always invoke the most heavily derived implementation, even if called from a pointer to the base class. However, the two languages differ on the semantics of virtual functions during object construction and destruction.

    C# objects exist as their final type before construction begins, whereas C++ objects change type during the construction process.

    Here's an example:

    class Base {
      Base() { f(); }
      virtual void f() { cout << 1; }
      void g() { f(); }
    class Derived : public Base {
      Derived() { f(); }
      virtual void f() { cout << 2; }

    When a Derived object is constructed, the object starts as a Base, then the Base::Base constructor is executed. Since the object is still a Base, the call to f() invokes Base::f and not Derived::f. After the Base::Base constructor completes, the object then becomes a Derived and the Derived::Derived constructor is run. This time, the call to f() invokes Derived::f.

    In other words, constructing a Derived object prints "12".

    Similar remarks apply to the destructor. The object is destructed in pieces, and a call to a virtual function invokes the function corresponding to the stage of destruction currently in progress.

    This is why some coding guidelines recommend against calling virtual functions from a constructor or destructor. Depending on what stage of construction/destruction is taking place, the same call to f() can have different effects. For example, the function Base::g() above will call Base::f if called from the Base::Base constructor or destructor, but will call Derived::f if called after the object has been constructed and before it is destructed.

    On the other hand, if this sample were written (with suitable syntactic changes) in C#, the output would be "22" because a C# object is created as its final type. Both calls to f() invoke Derived::f, since the object is always a Derived. Notice that means a method can be invoked on an object before its constructor has run. Something to bear in mind.

    Sometimes your C++ program may crash with the error "R6025 - pure virtual function call". This message comes from a function called __purecall. What does it mean?

    C++ and C# both have the concept of a "pure virtual function" (which C# calls "abstract"). This is a method which is declared by the base class, but for which no implementation is provided. In C++ the syntax for this is "=0":

    class Base {
      Base() { f(); }
      virtual void f() = 0;

    If you attempt to create a Derived object, the base class will attempt to call Base::f, which does not exist since it is a pure virtual function. When this happens, the "pure virtual function call" error is raised and the program is terminated.

    Of course, the mistake is rarely as obvious as this. Typically, the call to the pure virtual function occurs deep inside the call stack of the constructor.

    This raises the side issue of the "novtable" optimization. As we noted above, the identity of the object changes during construction. This change of identity is performed by swapping the vtables around during construction. If you have a base class that is never instantiated directly but always via a derived class, and if you have followed the rules against calling virtual methods during construction, then you can use the novtable optimization to get rid of the vtable swapping during construction of the base class.

    If you use this optimization, then calling virtual methods during the base class's constructor or destructor will result in undefined behavior. It's a nice optimization, but it's your own responsibility to make sure you conform to its requirements.

    Sidebar: Why does C# not do type morphing during construction? One reason is that it would result in the possibility, given two objects A and B, that typeof(A) == typeof(B) yet sizeof(A) != sizeof(B). This would happen if A were a fully constructed object and B were a partially-constructed object on its way to becoming a derived object.

    Why is this so bad? Because the garbage collector is really keen on knowing the size of each object so it can know how much memory to free. It does this by checking the object's type. If an object's type did not completely determine its size, this would result in the garbage collector having to do extra work to figure out exactly how big the object is, which means extra code in the constructor and destructor, as well as space in the object, to keep track of which stage of construction/destruction is currently in progress. And all this for something most coding guidelines recommend against anyway.

  • The Old New Thing

    What, going to Sweden *again*?


    It appears that I will have an opportunity to visit Sweden during the first week of June. I'll have three days in Uppsala and three days in Lund, with a travel day in between. Now, I've already spent a week and a half in Uppsala, so perhaps I could spend the Uppsala days taking a ferry to Helsinki and back. (And I could visit Denmark from Lund...)

    My Swedish won't be any better (well, okay, I learned a little more about formation of past participles, not like that counts for much), but I still enjoy trying. The hard part is finding someone patient enough to put up with all my fumbling and not switch to English out of frustration.

    (In Finland and Denmark, I'm just going to start in English with German as a fallback. Sorry, guys.)

    The question facing me now is whether I should go. It hasn't even been a month since my previous trip, and if the Finland thing doesn't come together, I'll be spending half my time in a city I've already visited. Hm...

  • The Old New Thing

    Why doesn't C# have "const"?


    I was going to write about why C# doesn't have "const", but Stan Lippman already discussed this in A Question of Const, so now I don't have to.

    (And another example of synchronicity: After I wrote up this item and tossed it into the queue, Eric Gunnerson took up the topic as well.

  • The Old New Thing

    Nobody said it was a democracy


    It's proxy season, which means I've been reading through proxy statement after proxy statement.

    The proxy voting rules for Allstate aren't very democratic. Scroll down to "How votes are counted and discretionary voting authority":

    The thirteen nominees who receive the most votes will be elected to the open directorships even if they get less than a majority of the votes.

    Okay, let's see, how many nominees are there? Oh, exactly thirteen.

    How convenient.

    In other words: These thirteen people will be elected to directorships regardless of what you do.

    So of course I voted against all of them.

    Later, I realized that I had fallen into their trap.

    You see, the only way I could stop these people from becoming directors was to withhold my vote and attempt to hinder a quorum. Under these rules, a "no" vote is as good as a "yes" vote!

    Allstate isn't the only company to rig their elections. Baxter and Wyeth (can't find proxy online) have similarly sham elections.

  • The Old New Thing

    In order to demonstrate our superior intellect, we will now ask you a question you cannot answer.


    During the development of Windows 95, a placeholder dialog was added with the title, "In order to demonstrate our superior intellect, we will now ask you a question you cannot answer." The dialog itself asked a technical question that you need a brain the size of a planet in order to answer. (Okay, your brain didn't need to be quite that big.)

    Of course, there was no intention of shipping Windows 95 with such a dialog. The dialog was there only until other infrastructure became available, permitting the system to answer the question automatically.

    But when I saw that dialog, I was enlightened. As programmers, we often find ourselves unsure what to do next, and we say, "Well, to play it safe, I'll just ask the user what they want to do. I'm sure they'll make the right decision."

    Except that they don't. The default answer to every dialog box is Cancel. If you ask the user a technical question, odds are they they're just going to stare at it blankly for a while, then try to cancel out of it. The lesson they've learned is "Computers are hard to use."

    Even Eric Raymond has discovered this. (Don't forget to read his follow-up.)

    So don't ask questions the user can't answer. It doesn't get you anywhere and it just frustrates the user.

  • The Old New Thing

    Musings on formal and informal address


    My entry about Good-Bye, Lenin! appears to have turned into a discussion of formal and informal terms of address in various languages and cultures.

    Sweden effectively abolished the "du"/"ni" distinction in the 1970's during the so-called "du-reform", getting rid of the formal "ni" and having everybody address each other as "du" - even the king and prime minister. (I'm told this is the same movement that also got people to greet each other with a simple "Hej!") There's a nice discussion of the du-reform from Language Hat. I found it particularly interesting that

    Swedes traditionally addressed anyone with a title by that title, using the third person: "Would the professor like more tea?" Thus the use of "Ni" was slightly derogatory, implying that one's interlocutor had no title or office worth bothering about.

    Of course, I didn't discover this until I had already addressed some people as "ni" and probably either amused or insulted them. (Possibly both.)

    In English, the use of third person address as a substitute for "you" is long gone, unless you intend to be obsequious to the point of being insulting: "Would the gentleman please take a seat." (I believe German has a similar insultingly-polite construction: "Wollen der Herr bitte Platz nehmen.")

    It seems to me that the use of the pure title as a form of direct address is largely gone in American English, with the exceptions of Speaker of the House, President, and Vice President, who are still "Madame Speaker" or "Mr. [Vice] President". Other public servants typically retain their office in addition to their surname, such as "Governor Smith", "Senator Jones", or "Secretary Green".

    In addition to public service, there are still a handful of other environments where titles are still used. Off the top of my head, I can think of religion ("Reverend Brown"), academia ("Professor Wilson"), medicine ("Dr. Miller"), and the military ("General Williams"). But you are not going to hear "Mr. Night Shift Manager" or "Account Representative Harrison".

  • The Old New Thing

    How to retrieve text under the cursor (mouse pointer)


    Microsoft Active Accessibilty is the technology that exposes information about objects on the screen to accessibility aids such as screen readers. But that doesn't mean that only screen readers can use it.

    Here's a program that illustrates the use of Active Accessibility at the most rudimentary level: Reading text. There's much more to Active Accessibility than this. You can navigate the objects on the screen, read various properties, even invoke commands on them, all programmatically.

    Start with our scratch program and change these two functions:

    OnCreate(HWND hwnd, LPCREATESTRUCT lpcs)
      SetTimer(hwnd, 1, 1000, RecalcText);
      return TRUE;
    PaintContent(HWND hwnd, PAINTSTRUCT *pps)
      if (g_pszText) {
          RECT rc;
          GetClientRect(hwnd, &rc);
          DrawText(pps->hdc, g_pszText, lstrlen(g_pszText),
                   &rc, DT_NOPREFIX | DT_WORDBREAK);

    Of course, the fun part is the function RecalcText, which retrieves the text from beneath the cursor:

    #include <oleacc.h>
    POINT g_pt;
    LPTSTR g_pszText;
    void CALLBACK RecalcText(HWND hwnd, UINT, UINT_PTR, DWORD)
      POINT pt;
      if (GetCursorPos(&pt) &&
        (pt.x != g_pt.x || pt.y != g_pt.y)) {
        g_pt = pt;
        IAccessible *pacc;
        VARIANT vtChild;
        if (SUCCEEDED(AccessibleObjectFromPoint(pt, &pacc, &vtChild))) {
          BSTR bsName = NULL;
          BSTR bsValue = NULL;
          pacc->get_accName(vtChild, &bsName);
          pacc->get_accValue(vtChild, &bsValue);
          LPTSTR pszResult;
          DWORD_PTR args[2] = { (DWORD_PTR)(bsName ? bsName : L""),
                                (DWORD_PTR)(bsValue ? bsValue : L"") };
          if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                            FORMAT_MESSAGE_FROM_STRING |
                            TEXT("Name: %1!ws!\r\n\r\nValue: %2!ws!"),
                            0, 0, (LPTSTR)&pszResult, 0, (va_list*)args)) {
            g_pszText = pszResult;
            InvalidateRect(hwnd, NULL, TRUE);

    Let's take a look at this function. We start by grabbing the cursor position and seeing if it changed since the last time we checked. If so, then we ask AccessibleObjectFromPoint to identify the object at those coordinates and give us an IAccessible pointer plus a child identifier. These two pieces of information together represent the object under the cursor.

    Now it's a simple matter of asking for the name (get_accName) and value (get_accValue) of the object and format it nicely.

    Note that we handled the NULL case of the BSTR in accordance with Eric's Complete Guide to BSTR Semantics.

    For more information about accessibility, check out Sara Ford's WebLog, in particular the bit titled What is Assistive Technology Compatibility.

Page 1 of 4 (36 items) 1234