3 ms·
Now that `mutable` exists const_cast should indeed be avoided. But `reinterpret_cast` has quite a bit of use, particularly in FFI scenarios. For example when u
by kllrnohj 7y ago
Now that `mutable` exists const_cast should indeed be avoided.
But `reinterpret_cast` has quite a bit of use, particularly in FFI scenarios. For example when using JNI there is no void* type in Java, so you are forced to store the pointer in a jlong. But you also need to be super duper sure that no conversion happens, it's _just_ a really tiny 8-byte allocation. So you reinterpret_cast back & forth. My JNI code is littered with variants of reinterpret_cast<jlong>( T* ) & reinterpret_cast< T* >(jlong) - and it is neither useless nor harmful.
reinterpret_cast is also quite useful when writing custom allocators. More niche usage there, of course, but still far from useless or harmful.
> 2. The only meaningful reason to prefer static_cast over C-style casts is easy greppability. If you find you don't benefit from this difference, C-style casts are just fine.
If you do actually think that static_cast is the only useful cast then this is super wrong advice. C-style casts are "compiler guesses if it's static_cast or reinterpret_cast, and const-ness is completely ignored." They are not a shortened alias for static_cast.
- JoeAltmaier 7y agoAgreed. But triggered by a thing written there: a pointer in a jlong? Is there any guarantee these things are the same size? Works on one platform, cool, maybe that's enough. But doesn't sound portable.
- klodolph 7y agojlong is always 64 bits. I would be interested in knowing more details about platforms where your pointers are wider than 64 bits. Not impossible, but certainly pathological.
- saagarjha 7y agoYeah, but a void pointer isn't always 64 bits…
- klodolph 7y agoI’m interested in the specific cases where it isn’t (where it’s larger than 64-bits). I can’t think of an example where a simple object pointer is larger than 64 bits. Can you run the JNI on those platforms?
- JoeAltmaier 7y agoComplex pointers (object/method pointers) can sometimes exceed that? Anyway, I see the issue, you're stuck having to do something and that's a pretty good solution. Maybe add an assert somewhere to the effect that sizeof(jlong) >= sizeof(pointer) which is free on your platform.
- klodolph 7y agoSure, but if you go down chasing portability guarantees in e.g. the C++ spec, you’re going to go insane pretty quickly.
- kllrnohj 7y ago> Complex pointers (object/method pointers) can sometimes exceed that? They can't. void* / intptr_t is a fixed-size, and at least on all platforms I run on that size is always 32-bit or 64-bit. Both of which fit perfectly fine in the always-64-bit jlong. If you're thinking of std::mem_fn or similar note that they are defined to return an undefined object not a pointer. So of course those can be larger than the size of a pointer, since they aren't a pointer. But sure toss in a static_assert(sizeof(jlong) >= sizeof(void*)) if you want.
- JoeAltmaier 7y agoI guess I was thinking of virtual function pointer. Its larger than a regular function pointer, which is not necessarily the same size as a data pointer. But if you're dealing with object pointers only, all good!
- keldaris 7y agoYeah, this is why I emphasized that these are prescriptions tailored to my personal usecases and style, not something that's supposed to work for everyone. I don't do anything remotely Java-related, so I have no opinion on your JNI example. On the latter point - yes, C-style casts are a broader concept than static_cast. In practice, as I said in another comment, the stricter constraints of static_cast have never prevented me from making a bug, so I don't view that as an advantage that would justify the extra verbosity. I do write custom allocators a lot and mostly find myself just using C-style casts there - that code already tends to be almost entirely C anyway and the logic of the casts tends to be extremely obvious from the context. If you really care about greppability to a religious extent, I suppose this is an argument for reinterpret_cast - I just don't find it convincing, personally.
- jfkebwjsbx 7y agoI prefer memcpy() for those (or a custom function that calls memcpy() for ergonomics and perhaps static_asserts something about the type) rather than reinterpret_cast since it risks UB if you get it wrong.