在指针和 intptr_t/uintptr_t之间进行强制转换时使用哪种强制转换?

Which cast to use when casting between pointers and intptr_t/uintptr_t?

提问人:user541686 提问时间:9/30/2023 更新时间:10/1/2023 访问量:124

问:

  1. 在将指针投射到 /从 或 时,您是否应该更喜欢其中之一或另一个,如果是这样,为什么一个比另一个更好?intptr_tuintptr_treinterpret_caststd::bit_cast

  2. 函数指针与对象指针的答案如何变化?

C++ 强制转换

评论

0赞 mch 10/1/2023
这回答了你的问题吗?将指针转换为整数
0赞 HolyBlackCat 10/1/2023
它们通常应该具有相同的效果,但没有人期望用于此目的。只需使用普通的 C++ 强制转换。bit_cast
0赞 Red.Wave 10/1/2023
bit_cast可以在上下文中使用。我想知道它必须在整数和指针类型之间转换什么实际用例;也许是使用背靠背转换的一些实现。constexproffsetof
0赞 Bob__ 10/1/2023
@Red.Wave 参见例如 stackoverflow.com/questions/35071200/...
0赞 Red.Wave 10/1/2023
@Bob__我关心的是上下文的有效用例。否则,分配器设计是通常应用非 consexpr 强制转换的领域。constexpr

答:

2赞 Andrey Semashev 10/1/2023 #1
  1. 在将指针投射到 /从 或 时,您是否应该更喜欢其中之一或另一个,如果是这样,为什么一个比另一个更好?intptr_tuintptr_treinterpret_caststd::bit_cast

如果可能的话,我更喜欢 ,因为:reinterpret_cast

  1. 它不需要 C++20,因此从 C++03 开始,在 C++ 版本中更具可移植性。

  2. 它不需要包含标准库标头,这使您的代码更加轻量级。虽然它本身不应该特别重(目前,从 C++23 开始),但它可能在内部包含标准库的其他部分,并最终将大量代码引入您的编译中。<bit>

更多关于何时可能仍然喜欢以下内容。std::bit_cast

  1. 函数指针与对象指针的答案如何变化?

C++ 标准引用了 / 定义的 C 标准,该标准表示这些是整数类型(分别为有符号和无符号),因此 (C99, 7.18.1.4):intptr_tuintptr_t

任何有效的指针 to 都可以转换为此类型,然后转换回 的指针 ,结果将与原始指针相等voidvoid

通过转换,这涵盖了所有指向对象的指针,因为任何有效的对象指针都可以无损地转换和转换回来(C99,6.3.2.3/1):void*

指向的指针可以转换为指向任何不完整或对象类型的指针或从指针转换。指向任何不完整或对象类型的指针可以转换为指向和返回的指针;结果应与原始指针相等。voidvoid

请注意,函数指针没有这样的保证。C++ 标准也没有提供任何更强的保证 - 无论是函数指针还是成员指针(参见 C++23、[conv.ptr]、[conv.mem] 和 [conv.fctptr])。

因此,为了回答您的问题,在符合要求的程序中不能用于在函数指针或指向成员和 / 的指针之间进行转换。在实践中,函数指针通常具有与对象指针相同的大小,并且您可以将它们向/向/向后转换而不会丢失。例如,请参阅此处。指向成员的指针(无论是成员函数还是成员数据)通常大于对象指针,这意味着您不能在不丢失的情况下强制转换它们。reinterpret_castintptr_tuintptr_tintptr_tuintptr_t

std::bit_cast适用于任何简单可复制的类型(包括函数指针和指向成员的指针),但它要求源类型和目标类型具有相同的大小。这意味着它适用于函数指针,只要它们的大小与 / 相同,但对于指向成员的指针,它很可能会失败。这样做的好处是,在编译时,它可以工作,并且需要按照标准工作。intptr_tuintptr_treinterpret_caststd::bit_cast

评论

0赞 user541686 10/1/2023
谢谢,似乎这涵盖了一切。+1