25

When using COM boolean values are to be passed as VARIANT_BOOL which is declared in wtypes.h as short. There are also predefined values for true and false:

#define VARIANT_TRUE ((VARIANT_BOOL)-1)
#define VARIANT_FALSE ((VARIANT_BOOL)0)

Which is the best way to convert from VARIANT_BOOL to C++ bool type? Obvious variants are:

  1. compare with VARIANT_FALSE

  2. simply cast to bool

Other ways can be easily invented.

Which is the best way to do this - most readable, most standart-compliant, least prone to accidential bugs planting and least prone to issues with porting to 64-bit platforms?

sharptooth
  • 167,383
  • 100
  • 513
  • 979

6 Answers6

33

Compare to VARIANT_FALSE. There is a lot of buggy code out there that mistakenly passes in the C++ bool true value (cast to the integer value 1) to a function expecting VARIANT_BOOL. If you compare to VARIANT_FALSE, you will still get the correct expected value.

1800 INFORMATION
  • 131,367
  • 29
  • 160
  • 239
11

I don't like to have to worry about compatibility between different boolean values, so I will normally write:

VARIANT_BOOL vb_bool = VARIANT_FALSE;

// ... vb_bool set to something by some other code

bool myBool = (vb_bool == VARIANT_TRUE);

Are there tinier (as in "will compile to simpler x86 code"), valid ways to do it? Of course. Not worth it. This is guaranteed to work, so I can worry about my business logic.

Euro Micelli
  • 33,285
  • 8
  • 51
  • 70
4

Casting to bool is obviously wrong. Some people say (e.g. comments at BOOL vs. VARIANT_BOOL vs. BOOLEAN vs. bool) to compare to VARIANT_FALSE, but I would compare to both. That way you catch invalid values (anything but VARIANT_FALSE or VARIANT_TRUE) early.

e.g.

bool VariantBoolToBool(VARIANT_BOOL varFlag)
{
  bool boolFlag;

  switch( varFlag ) 
  {
    case VARIANT_TRUE:
        boolFlag = true;
        break;
    case VARIANT_FALSE:
        boolFlag = false;
        break;
    default:
        throw Exception("Not a valid value");
  }

  return boolFlag;
}
Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
  • Maybe assert(varFlag == VARIANT_FALSE || varFlag == VARIANT_TRUE)? – Andreas Magnusson May 20 '09 at 10:50
  • This is worth considering, but I would prefer exceptions in a C++ app. One reason (besides the other benefits to exceptions) is that I think the check should be in the production code, and assertions tend to wind up disabled. – Matthew Flaschen May 21 '09 at 08:52
  • 1
    Some checks should be done in production code, some in development code. I typically draw the line at what is a programmer error (e.g. passing a null-ptr to a function not accepting it) and external error (e.g. not finding a certain file). In my book conversion functions such as this one are typically more related to programmer errors than to external errors. – Andreas Magnusson Jun 21 '09 at 00:21
3

Why have an explicit cast?

if (my_bool)
{
    blargh();
}
else
{
   blarglerr();
}

This way, true is true and false is false, as per the C standard. If you need to SET a C++ style bool then do something like:

VARIANT_BOOL vb_bool = VARIANT_FALSE
bool cpp_bool = !!vb_bool
Pod
  • 3,938
  • 2
  • 37
  • 45
3

Declare this macro in one of your global headers.

#define b(X) ((X)!=VARIANT_FALSE)


EDIT: Much safer version:

inline bool b(VARIANT_BOOL v){return v!=VARIANT_FALSE;}
Jesus Fernandez
  • 1,170
  • 2
  • 10
  • 23
0

Standard C++ conversion rules rely on zero meaning false [and as 1800 INFORMATION points out, the TRUE variant is where the most confusion happens] and nothing more. Hence a static_cast would be best.

But in many cases, the code would be more readable as a comparison. In that case, VARIANT_BOOL is the thing to compare with.

Ruben Bartelink
  • 59,778
  • 26
  • 187
  • 249