I think assigning and int value to an enum variable is invalid in C , and there's already questions verify this, such as cannot initialize a variable of type 'designFlags' with an rvalue of type 'int' .
However I just see the following code not causing compile error:
// https://github.com/opencv/opencv/blob/4.x/modules/core/include/opencv2/core/mat.hpp#L158-L265
class CV_EXPORTS _InputArray
{
public:
enum KindFlag { //!! KindFlag is an enum type
KIND_SHIFT = 16,
FIXED_TYPE = 0x8000 << KIND_SHIFT,
FIXED_SIZE = 0x4000 << KIND_SHIFT,
KIND_MASK = 31 << KIND_SHIFT,
...
}
...
};
// https://github.com/opencv/opencv/blob/4.x/modules/core/src/matrix_wrap.cpp#L370-L378
_InputArray::KindFlag _InputArray::kind() const
{
KindFlag k = flags & KIND_MASK; //!! this line, I think it is assign enum type var `k` with int value `flag & KIND_MASK`, but it it not cause compile error
#if CV_VERSION_MAJOR < 5
CV_DbgAssert(k != EXPR);
CV_DbgAssert(k != STD_ARRAY);
#endif
return k;
}
I try to implement a minimal InputArray_ class with the following, which will cause compile error, with the same assigne as above, which make me confused:
// what.cpp
class InputArray_
{
public:
enum KindFlag {
KIND_SHIFT = 16,
KIND_MASK = 31 << KIND_SHIFT,
NONE = 0 << KIND_SHIFT,
MAT = 1 << KIND_SHIFT
};
bool empty() const;
InputArray_::KindFlag kind() const;
public:
InputArray_();
protected:
int flags;
void* obj;
};
InputArray_::KindFlag InputArray_::kind() const
{
KindFlag k = flags & KIND_MASK; //!! now this cause compile error
return k;
}
int main()
{
}
The compiler is AppleClang 13.0.0, the full error message is:
what.cpp:26:14: error: cannot initialize a variable of type 'InputArray_::KindFlag' with an rvalue of type 'int'
KindFlag k = flags & KIND_MASK;
^ ~~~~~~~~~~~~~~~~~
1 error generated.
Anyone know why OpenCV's one won't cause compile error?
CodePudding user response:
opencv define the operator & itself so it no more result in int
you can see it just below the section you linked
__CV_ENUM_FLAGS_BITWISE_AND(_InputArray::KindFlag, int, _InputArray::KindFlag)
Implementation of the macro
#define __CV_ENUM_FLAGS_BITWISE_AND(EnumType, Arg1Type, Arg2Type) \
static inline EnumType operator&(const Arg1Type& a, const Arg2Type& b) \
{ \
typedef std::underlying_type<EnumType>::type UnderlyingType; \
return static_cast<EnumType>(static_cast<UnderlyingType>(a) & static_cast<UnderlyingType>(b)); \
}
