July 31st, 2025
mind blown1 reaction

A consequence of the weird wReserved value at the start of the DECIMAL structure

Not too long ago, I explained why why there is a weird wReserved value at the start of the DECIMAL structure. Markus Grohs pointed out in a comment that the way that decVal is overlaid on top of a VARIANT means that you have to be careful about the order in which you set the fields.

Given

DECIMAL value = ⟦ some value ⟧;
VARIANT var;
VariantClear(&var);

then you have to remember to set the vt last because it is overwritten by the wReserved inside the DECIMAL.

// Wrong
var.vt = VT_DECIMAL;
var.decVal = value; // oops, the wReserved overwrites the var.vt.

// Better
var.decVal = value; // the wReserved overwrites var.vt
var.vt = VT_DECIMAL; // but we fix it up immediately

The extra wReserved in the DECIMAL is like a bulky backpack that you wear as you go about your daily business. You usually forget that you have it on, until you turn around in a tight spot and accidentally knock something over.

Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

3 comments

Sort by :
  • Dave Gzorple

    And then the compiler, assuming it’s gcc, knows that it can assign the fields in any order so it swaps the two around, then sees that the vt gets overwritten so optimises it out, and your careful:

    // Better
    var.decVal = value; // the wReserved overwrites var.vt
    var.vt = VT_DECIMAL; // but we fix it up immediately

    gets turned into:

    // Better
    var.decVal = value; // the wReserved overwrites var.vt
    

    This is not snark, gcc will actually do things like this, leaving you with almost-impossible-to-find bugs.

    • Stephan Leclercq 20 hours ago · Edited

      I would say that gcc can reorder assignment of fields of a struct, but here decVal and vt overlap, so they obviously must be in an union (I checked the spec, they are indeed) and gcc won’t re-order that.

      Also, wouldn’t you get a compiler warning that the value assigned to vt is overwritten by the assignme to decVal?

      • Dave Gzorple

        With gcc you never can tell, code that's fine with one release can silently break on the next one as someone introduces a new "clever" optimisation. So it's hard to say one way or the other.

        In terms of warning, the gcc philosophy is not to warn since you, the developer, should have known better. An example of this from a few years ago is the nonnull attribute, which you can decorate function parameters with to indicate that it's an error if a null pointer is passed in for that parameter. You'd expect gcc to report an error,...

        Read more