c++ - 将 size_t* 转换为 hsize_t*
问题描述
在我的平台上,size_t
HDF5hsize_t
都是无符号的 64 位整数,但它们是不同的 C++ 类型(一种是unsigned long
,另一种unsigned long long
),不能互换使用。
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
}
所以我的问题是:在这种情况下是否需要转换
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());
}
或者我可以简单地投吗?
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?
}
(这可以编译,但可以保证正常工作吗?)
解决方案
reinterpret_cast
如果这两种类型在 cv 限定范围内确实是不同的非char
整数类型,而这些类型不是彼此的unsigned
/signed
版本,则通过 的结果指针访问该值是一种别名冲突。既然你说这里的两种类型是unsigned long
and unsigned long long
,这适用于你的情况。
如果您想保持在标准定义的范围内,则不能使用它。也无法将一种整数类型键入另一种整数类型,因此您总是需要复制(编译器可能会也可能不会优化)。
您通常仍然可以在实践中进行这项工作(即使根据标准它是未定义的行为),方法是设置一些编译器标志-fno-strict-aliasing
,例如指示编译器不根据别名规则给予它的保证进行优化(可能会出现性能更差)或通过将违规指针访问“隐藏”到优化器中,将其放入不同的翻译单元(如果未使用链接时间优化)。另请参阅@HolyBlackCat 对该问题的评论。
但是,两者都将是不可移植的。例如,不同的编译器(版本)可能默认进行链接时优化或不支持-fno-strict-aliasing
或类似的。