提问人:user541686 提问时间:9/30/2023 更新时间:10/1/2023 访问量:124
在指针和 intptr_t/uintptr_t之间进行强制转换时使用哪种强制转换?
Which cast to use when casting between pointers and intptr_t/uintptr_t?
问:
在将指针投射到 /从 或 时,您是否应该更喜欢其中之一或另一个,如果是这样,为什么一个比另一个更好?
intptr_t
uintptr_t
reinterpret_cast
std::bit_cast
函数指针与对象指针的答案如何变化?
答:
- 在将指针投射到 /从 或 时,您是否应该更喜欢其中之一或另一个,如果是这样,为什么一个比另一个更好?
intptr_t
uintptr_t
reinterpret_cast
std::bit_cast
如果可能的话,我更喜欢 ,因为:reinterpret_cast
它不需要 C++20,因此从 C++03 开始,在 C++ 版本中更具可移植性。
它不需要包含标准库标头,这使您的代码更加轻量级。虽然它本身不应该特别重(目前,从 C++23 开始),但它可能在内部包含标准库的其他部分,并最终将大量代码引入您的编译中。
<bit>
更多关于何时可能仍然喜欢以下内容。std::bit_cast
- 函数指针与对象指针的答案如何变化?
C++ 标准引用了 / 定义的 C 标准,该标准表示这些是整数类型(分别为有符号和无符号),因此 (C99, 7.18.1.4):intptr_t
uintptr_t
任何有效的指针 to 都可以转换为此类型,然后转换回 的指针 ,结果将与原始指针相等
void
void
通过转换,这涵盖了所有指向对象的指针,因为任何有效的对象指针都可以无损地转换和转换回来(C99,6.3.2.3/1):void*
指向的指针可以转换为指向任何不完整或对象类型的指针或从指针转换。指向任何不完整或对象类型的指针可以转换为指向和返回的指针;结果应与原始指针相等。
void
void
请注意,函数指针没有这样的保证。C++ 标准也没有提供任何更强的保证 - 无论是函数指针还是成员指针(参见 C++23、[conv.ptr]、[conv.mem] 和 [conv.fctptr])。
因此,为了回答您的问题,在符合要求的程序中不能用于在函数指针或指向成员和 / 的指针之间进行转换。在实践中,函数指针通常具有与对象指针相同的大小,并且您可以将它们向/向/向后转换而不会丢失。例如,请参阅此处。指向成员的指针(无论是成员函数还是成员数据)通常大于对象指针,这意味着您不能在不丢失的情况下强制转换它们。reinterpret_cast
intptr_t
uintptr_t
intptr_t
uintptr_t
std::bit_cast
适用于任何简单可复制的类型(包括函数指针和指向成员的指针),但它要求源类型和目标类型具有相同的大小。这意味着它适用于函数指针,只要它们的大小与 / 相同,但对于指向成员的指针,它很可能会失败。这样做的好处是,在编译时,它可以工作,并且需要按照标准工作。intptr_t
uintptr_t
reinterpret_cast
std::bit_cast
评论
bit_cast
bit_cast
可以在上下文中使用。我想知道它必须在整数和指针类型之间转换什么实际用例;也许是使用背靠背转换的一些实现。constexpr
offsetof
constexpr