简体   繁体   中英

Usage of signed vs unsigned variables for flags in C++

Is there any "good practice" or habit of using signed variables vs unsigned variables for flags? Personally I would use unsigned variable, but I can see even signed variable used for flags in some code. I mean especially in library interface where it matters.

UDPATE I cannot accept answer "use Enum", because it is implementation dependent and this it cannot be used in library interface.

I think an unsigned type is a better representation of a set of flags. Since you need a specific amount of equivalent bits to represent your flags. In a signed type the first bit is kind of special.

Probably the std::bitset could also meet your requirements. And will serve you with the basic logical operators and conversion methods.

#include <iostream>
#include <bitset>
using namespace std;

int main() {
    std::bitset<4> flags;
    flags.set(1);
    flags.set(3);
    std::cout << flags.to_string() << std::endl;
    std::cout << flags.to_ulong() << std::endl;
    return 0;
}

DEMO

It is known that the flags are always non-negative integers, but why would you use int / unsigned int / short / unsigned short for a flag? Use #define , or even better, enum type.

enum flags
{
    FLAG0 = 0,
    FLAG1 = 1,
    FLAG2 = 2,
    ...
    FLAGN = n
};

If you decide to use enum for your flags, here is a useful macro that creates code for bitwise operators for your enum type.

#define GENERATE_ENUM_FLAG_OPERATORS(enumType) \
    inline enumType operator| (enumType lhs, enumType rhs) \
    { \
        return static_cast<enumType>(static_cast<int>(lhs) | static_cast<int>(rhs)); \
    } \
    inline enumType& operator|= (enumType& lhs, const enumType& rhs) \
    { \
        lhs = static_cast<enumType>(static_cast<int>(lhs) | static_cast<int>(rhs)); \
        return lhs; \
    } \
    inline enumType operator& (enumType lhs, enumType rhs) \
    { \
        return static_cast<enumType>(static_cast<int>(lhs) & static_cast<int>(rhs)); \
    } \
    inline enumType& operator&= (enumType& lhs, const enumType& rhs) \
    { \
        lhs = static_cast<enumType>(static_cast<int>(lhs) & static_cast<int>(rhs)); \
        return lhs; \
    } \
    inline enumType operator~ (const enumType& rhs) \
    { \
        return static_cast<enumType>(~static_cast<int>(rhs)); \
    }

Usage:

enum Test
{
    TEST_1 = 0x1,
    TEST_2 = 0x2,
    TEST_3 = 0x4,
};
GENERATE_ENUM_FLAG_OPERATORS(Test);

Test one = TEST_1;
Test two = TEST_2;

Test three = one | two;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM