如何将 Void* 转换为 size_t?

How to Convert Void* into 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* 即指向数字的指针?这甚至是合法的吗?

How may I convert void* ie a pointer to number?

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

但是,就 C++ 语言而言,除了将其从 std::uintptr_t 转换回相同的指针类型将导致相同的指针值外,无法保证结果数字。

plus can you show some code?

示例:

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

why reinterpret_cast not (uintptr_t)?

显式转换(也称为 C 风格强制转换)的行为取决于操作数的类型。有些演员是不安全的,而其他演员是良性的。通常简单的错误会导致预期的安全转换意外地不安全,从而导致未定义的行为(这非常糟糕)——而正确的 C++ 风格转换会导致编译错误,从而导致错误检测(这非常好)。

在 reinterpret_cast 的情况下,我们正在进行这种不安全的转换,因此没有安全方面的问题,但 C++ 风格转换的重要性在于将缺乏安全性传达给 reader程序。

不要在 C++ 中使用 C 风格的转换。你什么都不需要它们。