Home > Net >  Why is assigning an int to enum type valid in OpenCV _InputArray::kind()?
Why is assigning an int to enum type valid in OpenCV _InputArray::kind()?

Time:12-13

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)

link


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));    \
}                                                                                                    

link

  • Related