Is it UB to reference bind to underlying type of enum class
object?
I'm aware of the danger of pass-through return reference of the as_int
function. The thunking function is just to help explain the question.
XY problem - after a bunch of inline operators to static_cast
to/from underlying type at appropriate places, I found this to be an easier to use alternative in places. But I am unsure if it is undefined behavior, and the reinterpret_cast
takes off the safety. The public facing API of the enum class
would not expose this pattern; it is just for private use in the implementation file.
#include <iostream>
using std::cout;
enum class Int : int {};
inline auto as_int(Int& i) -> int& {
return reinterpret_cast<int&>(i);
}
int main() {
Int i{100};
int& r = as_int(i);
cout << r << "\n"; //> 100
as_int(i) = 107;
cout << r << "\n"; //> 107
}
CodePudding user response:
Accessing the return value of as_int(i)
as done in your main
is an aliasing violation and therefore causes undefined behavior. The relevant paragraph of the standard ([basic.lval]/11) does not list underlying types of enumeration types as specifically allowed to alias.
Currently the standard doesn't even specify that the enumeration type and the underlying type will share the same alignment. If it was different then the cast would not even preserve the value (so that a round-trip cast would be unsafe). But that seems like a defect, see CWG 2590.
Alignment issues aside, the cast itself does not have undefined behavior, but accessing the enumeration object through the resulting reference does.