首页 > 解决方案 > 将 size_t* 转换为 hsize_t*

问题描述

在我的平台上,size_tHDF5hsize_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?
 }

(这可以编译,但可以保证正常工作吗?)

标签: c++castingtype-conversioninteger

解决方案


reinterpret_cast如果这两种类型在 cv 限定范围内确实是不同的非char整数类型,而这些类型不是彼此的unsigned/signed版本,则通过 的结果指针访问该值是一种别名冲突。既然你说这里的两种类型是unsigned longand unsigned long long,这适用于你的情况。

如果您想保持在标准定义的范围内,则不能使用它。也无法将一种整数类型键入另一种整数类型,因此您总是需要复制(编译器可能会也可能不会优化)。


您通常仍然可以在实践中进行这项工作(即使根据标准它是未定义的行为),方法是设置一些编译器标志-fno-strict-aliasing,例如指示编译器不根据别名规则给予它的保证进行优化(可能会出现性能更差)或通过将违规指针访问“隐藏”到优化器中,将其放入不同的翻译单元(如果未使用链接时间优化)。另请参阅@HolyBlackCat 对该问题的评论。

但是,两者都将是不可移植的。例如,不同的编译器(版本)可能默认进行链接时优化或不支持-fno-strict-aliasing或类似的。


推荐阅读