问题描述
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 风格的强制转换。你不需要它们做任何事情。