I have a C API that defines an enum like so:
typedef enum
{
C_ENUM_VALUE_NONE = 0,
C_ENUM_VALUE_APPLE = (1 << 0),
C_ENUM_VALUE_BANANA = (1
By or-ing two enum values, you're creating an invalid value (0x3 is not in enum CEnumType). Enumerations are not bitfields. If you want a bitfield, define one.
You can cast the value if you want to force it through, but that may surprise some code that is counting on only being able to get the enumerated values.
do_something((CEnumType)(C_ENUM_VALUE_APPLE | C_ENUM_VALUE_BANANA));
In the case of bitwise operations, the expression evaluates to a primitive type, i.e. int
, long
, etc. However, your function takes a non-primitive type (CEnumType
). The only way I know of to bypass this is to cast the expression. For example:
do_something((CEnumType) (C_ENUM_VALUE_APPLE | C_ENUM_VALUE_BANANA));
C++ has stricter rules than C regarding enums. You'll need to cast the value to the enumeration type when calling:
do_something((CEnumType)(C_ENUM_VALUE_APPLE | C_ENUM_VALUE_BANANA));
Alternatively, you can writer a wrapper function that takes an int
to do the cast for you, if you want to avoid writing the cast every time you call it:
void do_something_wrapper(int types)
{
do_something((CEnumType)types);
}
...
do_something_wrapper(C_ENUM_VALUE_APPLE | C_ENUM_VALUE_BANANA);
Though I don't know if I want to see what you get when you cross an apple with a banana...
You need to cast int
s to enums in C++, but you can hide the cast in a custom OR
operator:
CEnumType operator|(CEnumType lhs, CEnumType rhs) {
return (CEnumType) ((int)lhs| (int)rhs);
}
With this operator in place, you can write your original
do_something(C_ENUM_VALUE_APPLE | C_ENUM_VALUE_BANANA);
and it will compile and run without a problem.
CEnumType A;
A = (CEnumType)(A | C_ENUM_VALUE_APPLE);
You can use it this way too.