gpt4 book ai didi

c++ - 从 long 转换为相同大小的 int 失败

转载 作者:行者123 更新时间:2023-11-30 03:14:15 25 4
gpt4 key购买 nike

我尝试将 long 数组转换为相同大小的整数数组 ( godbolt ):

#include <cstdint>
#include <cstddef>
#include <cstring>

template<int> struct sized_int_ {};
template<> struct sized_int_<8> { typedef int64_t type; };
template<> struct sized_int_<4> { typedef int32_t type; };
typedef sized_int_<sizeof(long)>::type long_t;

void funcA(int32_t* array, std::size_t s); // defined somewhere else
void funcA(int64_t* array, std::size_t s); // defined somewhere else

// technically illegal cast
void funcB(long* array, std::size_t s) {
funcA(static_cast<long_t*>(array), s);
}

// memcpy
void funcC(long* array, std::size_t s) {
long_t* tmp = new long_t[s];
memcpy(tmp, array, s*sizeof(long_t));
funcA(tmp, s);
delete[] tmp;
}

int main() {
long x[] = {2, 3};
static_assert(sizeof(long_t)==sizeof(long), "Sizes don't match");
funcB(x, 2);
funcC(x, 2);
return 0;
}

g++ 愉快地接受代码,但 MacOS 上的 clang 不接受(error: static_cast from 'long *' to 'long_t *' (aka 'long long *') is not allowed)。 reinterpret_cast 在这两种情况下都有效,但它也允许我从 int32_t* 转换为 int64_t*

至少 clang 和 gcc 使用 -O2 没有优化分配临时数组并将数据复制到其中的正确方法。

如何将 long* 安全地转换为相应的 intX_t*

最佳答案

How can I cast long to the corresponding intX_t safely?

你不需要施法。转换是隐式的:

long x = 2;
long_t y = x;

但是如果你想显式的话你可以使用静态转换:

long_t y = static_cast<long_t>(x);

指针欺骗意味着您可能想就地处理对象。这当然要求类型具有相同的表示,这是相当合理的假设,但不能保证。但即使是这样的假设在技术上也不足以根据标准很好地定义通过 reinterpret_cast 的间接寻址。

您可以通过创建所需类型的对象在技术上重用存储:

long_t temp = x;
long_t* reused_x = new(&x) long_t(temp);

重用后,如果不能通过清洗存储 placement new 返回的指针,则可以将指针动态转换为 x。请注意,如果没有上面的新展示位置,洗钱是不够的。

long_t* converted = std::launder(reinterpret_cast<long_t*>(&x));

同样可以在数组循环中完成:

template<class T, class F> // types To and From
T* reuse_array(F* first, F* last, T* d_first) {
for (F* ptr = first; ptr != last; ++d_first, (void) ++ptr) {
T value = *ptr;
::new (ptr) T(value);
}
return std::launder(reinterpret_cast<T*>(first));
}

这甚至可以通过使用 std::memcpy 的结构来完成,只要它们是普通可复制和可破坏的。一个相当好的优化器应该 elide the copies .请注意,x 的生命周期已结束,可能不再使用。

有一个proposalstd::bless 引入语言中,这样在这种情况下就不需要显式创建对象了。

关于c++ - 从 long 转换为相同大小的 int 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58014104/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com