How should C bitflag enumerations be translated in

2019-02-18 13:25发布

C++ is mostly a superset of C, but not always. In particular, while enumeration values in both C and C++ implicitly convert into int, the reverse isn't true: only in C do ints convert back into enumeration values. Thus, bitflags defined via enumeration declarations don't work correctly. Hence, this is OK in C, but not in C++:

typedef enum Foo
{
    Foo_First = 1<<0,
    Foo_Second = 1<<1,
} Foo;

int main(void)
{
    Foo x = Foo_First | Foo_Second; // error in C++
    return 0;
}

How should this problem be handled efficiently and correctly, ideally without harming the debugger-friendly nature of using Foo as the variable type (it decomposes into the component bitflags in watches etc.)?

Consider also that there may be hundreds of such flag enumerations, and many thousands of use-points. Ideally some kind of efficient operator overloading would do the trick, but it really ought to be efficient; the application I have in mind is compute-bound and has a reputation of being fast.

Clarification: I'm translating a large (>300K) C program into C++, so I'm looking for an efficient translation in both run-time and developer-time. Simply inserting casts in all the appropriate locations could take weeks.

标签: c++ c enums flags
3条回答
该账号已被封号
2楼-- · 2019-02-18 13:44

Why not just cast the result back to a Foo?

Foo x = Foo(Foo_First | Foo_Second);

EDIT: I didn't understand the scope of your problem when I first answered this question. The above will work for doing a few spot fixes. For what you want to do, you will need to define a | operator that takes 2 Foo arguments and returns a Foo:

Foo operator|(Foo a, Foo b)
{
    return Foo(int(a) | int(b));
}

The int casts are there to prevent undesired recursion.

查看更多
不美不萌又怎样
3楼-- · 2019-02-18 13:48

It sounds like an ideal application for a cast - it's up to you to tell the compiler that yes, you DO mean to instantiate a Foo with a random integer.

Of course, technically speaking, Foo_First | Foo_Second isn't a valid value for a Foo.

查看更多
乱世女痞
4楼-- · 2019-02-18 13:59

Either leave the result as an int or static_cast:

Foo x = static_cast<Foo>(Foo_First | Foo_Second); // not an error in C++
查看更多
登录 后发表回答