如何将 Void* 转换为 size_t?

问题描述

我有以下功能

size_t calc_allign(size_t num) {
    return ((num + 7) & (-8)) - num;
}

并想像这样使用它:

int start_allign = calc_align (sbrk(0));

但我收到错误

error: no matching function for call to 'calc_align'
candidate function not viable: cannot convert argument of incomplete type 'void *' to 'size_t' (aka 'unsigned long') for 1st argument
size_t calc_align(size_t num) {

我如何转换 void* 即指向数字的指针?这甚至是合法的吗?

解决方法

如何转换 void*,即指向数字的指针?

您可以 reinterpret_cast 指向 std::uintptr_t(或有符号的等价物)的指针类型。然后,您可以进一步转换为另一种整数类型,例如 std::size_t,并且该转换可以是隐式的。理论上,后一种转换在 std::size_t 是较小类型的系统上可能是有损的。

然而,就 C++ 语言而言,除了将其从 std::uintptr_t 转换回相同的指针类型将导致相同的指针值之外,不能保证结果数。

加上你能展示一些代码吗?

示例:

void* ptr = sbrk(0);
auto numptr = reinterpret_cast<std::uintptr_t>(ptr);
static_assert(sizeof(std::size_t) >= std::uintptr_t,"Sorry,it isn't possible to represents pointers using std::size_t on this system");
std::size_t example = numptr;

auto ptr2 = reinterpret_cast<void*>(numptr);
assert(ptr2 == ptr); // guaranteed to pass

为什么不 reinterpret_cast (uintptr_t)?

显式转换(又名 C 样式转换)的行为取决于操作数的类型。一些演员是不安全的,而另一些是良性的。通常,简单的错误会导致预期的安全转换无意中变得不安全,从而导致未定义的行为(这是非常糟糕的)——而正确的 C++ 样式转换会导致编译错误,从而导致错误的检测(这是非常好的)。>

在 reinterpret_cast 的情况下,我们正在执行这种不安全的强制转换,因此没有安全方面,但 C++ 风格强制转换的重要性在于向程序的读者传达缺乏安全性。

不要在 C++ 中使用 C 风格的强制转换。你不需要它们做任何事情。