Reputation: 45444
On my platform, size_t
and HDF5's hsize_t
are both unsigned 64bit integers, yet they are different C++ types (one is unsigned long
, the other unsigned long long
) and cannot be used interchangibly.
using hsize_t = unsigned long long;
void library_function(const hsize_t*);
void client_code(std::vector<size_t> const&input)
{
library_function(input.data()); // error
}
So my question: Is it in this situation required to convert
void client_code(std::vector<size_t> const&input)
{
std::vector<hsize_t> tmp(input.size());
std::transform(input.begin(), input.end(), tmp.begin(),
[](size_t x) { return hsize_t(x); });
library_function(tmp.data());
}
or can I simply cast?
void client_code(std::vector<size_t> const&input)
{
static_assert(sizeof(size_t)==sizeof(hsize_t),"!!");
library_function(reinterpret_cast<const hsize_t*>(input.data())); // correct?
}
(this compiles, but is it guaranteed to work correctly?)
Upvotes: 0
Views: 1134
Reputation: 22152
Accessing the value through the resulting pointer of the reinterpret_cast
is an aliasing violation if the two types are indeed, up to cv-qualification, different non-char
integer types that are not unsigned
/signed
versions of one another. Since you said that the two types here are unsigned long
and unsigned long long
, this applies to your case.
You cannot use it if you want to stay in the bounds of what the standard defines. There is also no way to type-pun one integer type to another, so you always need to copy (that may or may not be optimized out by the compiler).
You can usually still make this work in practice (even though it is undefined behavior according to the standard) by either setting some compiler flag like -fno-strict-aliasing
which instructs the compiler to not optimize based on the guarantees given to it by the aliasing rule (which may come with worse performance) or by "hiding" the violating pointer access from the optimizer by putting it in a different translation unit (if link-time-optimization is not used). See also @HolyBlackCat's comment on the question.
Either is going to be unportable though. E.g. a different compiler (version) might do link-time optimization by default or not support the -fno-strict-aliasing
or similar.
Upvotes: 3