【问题标题】:How to Convert Void* into size_t?如何将 Void* 转换为 size_t?
【发布时间】:2021-07-02 07:53:13
【问题描述】:

我有以下功能:

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* 即指向数字的指针?这还合法吗?

【问题讨论】:

    标签: c++ type-conversion void size-t sbrk


    【解决方案1】:

    如何转换 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 风格的强制转换。你什么都不需要。

    【讨论】:

    • 为什么 reinterpret_cast 不是 (uintptr_t)?
    • 谢谢,最后一件事:关于抱歉消息,如果我将函数更改为采用 uintptr_t 而不是 size_t 会涵盖这两种情况,即两者都足够大吗?
    • 我的新函数:uintptr_t calc_align(uintptr_t num) { return ((num + 7) &amp; (-8)) - num; } 希望我没有因为从 int 移动到 uintptr_t 而破坏它的功能
    • Nitpick:reinterpret_cast 保护你不被意外const_casting,还有一个安全方面
    猜你喜欢
    • 2014-09-13
    • 2018-02-24
    • 2020-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多