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.
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:
gets turned into:
This is not snark, gcc will actually do things like this, leaving you with almost-impossible-to-find bugs.
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?
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,...