Luis Luis - 1 year ago 40
C++ Question

Is it safe to convert a pointer to typed/sized enum to a pointer to the underlying type?

The following code:

void f(const uint8_t* a) {} // <- this is an external library function
enum E : uint8_t { X, Y, Z };

int main(void) {
E e = X;
f(&e); // <- error here
}


Produces the following error:

/tmp/c.cc:10:3: error: no matching function for call to 'f'
f(&e);
^
/tmp/c.cc:5:6: note: candidate function not viable: no known conversion from 'E *' to 'const uint8_t *' (aka 'const unsigned char *') for 1st argument
void f(const uint8_t* e) { }


Which is surprising to me because I thought the
: uint8_t
in the enum's definition would mean they are necessarily represented with that underlying type. I can easily get around this with a cast:

f((uint8_t*)&e);


which I don't mind too much, but given that it's an error to omit it, is this always safe or is the
: uint8_t
not providing the guarantees I think it is?

Answer Source

It is indeed safe (although I'm not a language-lawyer): What's stored in memory is a uint8_t, and that's what you'll be pointing at. However, if f() were to take a pointer to a non-const uint8_t, then it could potentially change the value to something that's not a valid E value.

... but as others suggest, you're not getting the error because of your notion of safety, but because implicit conversions aren't performed between pointed-too types. You can pass an E to a function taking a uint8_t, but not an E * to a function taking a uint8_t *; that would be - according to the language committee and in my opinion as well - an overly cavalier attitude to pointer types.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download