【问题标题】:What's the difference between *uint and uintptr in Golang?Golang 中的 *uint 和 uintptr 有什么区别?
【发布时间】:2019-11-26 02:02:34
【问题描述】:

根据Golang tour,我们提供了以下整数类型:

int  int8  int16  int32  int64
uint uint8 uint16 uint32 uint64 uintptr

理论上,这意味着我们还可以拥有指向所有这些类型的指针,如下所示:

*int  *int8  *int16  *int32  *int64
*uint *uint8 *uint16 *uint32 *uint64 *uintptr

如果是这种情况,那么我们已经有一个指向 *uint 形式的 uint 的指针。这将使 uintptr 变得多余。 official documentation 对此并没有太多说明:

uintptr is an integer type that is large enough to hold the bit pattern of any pointer.

据我了解,这意味着 uint 的位宽是在编译时根据目标架构(通常是 32 位或 64 位)确定的。指针宽度也应该扩展到目标体系结构似乎是合乎逻辑的(即:32 位 *uint 指向 32 位 uint)。 Golang 是这样的吗?

另一个想法是添加 uintptr 是为了在执行多重间接时减少语法混乱(IE:foo *uinptr vs foo **uint)?

我最后的想法是,指针和整数在 Golang 中可能是不兼容的数据类型。这将非常令人沮丧,因为硬件本身并没有在它们之间做出任何区分。例如,“分支到此地址”指令可以使用来自刚刚在“添加此值”指令中使用的同一寄存器中的相同数据。

uintptr 的真正意义(双关语)是什么?

【问题讨论】:

  • uintptr 基本上是一个指向任何东西的不安全指针,与 uint 无关。
  • 我好像忘记了在 64 位系统上运行的 32 位代码。在这种情况下,*uint 将是 4 个字节,而 uintptr 将是 8 个字节。确实,看起来它们是无关的。

标签: pointers go


【解决方案1】:

简短的回答是“永远不要使用uintptr”。 ?

答案很长,uintptr 可以绕过类型系统并允许 Go 实现者在 Go 中编写 Go 运行时库,包括垃圾收集系统,并调用 C 可调用代码,包括使用 C 的系统调用Go 根本不处理的指针。

如果您是实现者(例如,在新操作系统上提供对系统调用的访问权限),您将需要 uintptr。您还需要了解使用它所需的所有特殊魔法,例如,如果操作系统要对操作系统级线程执行堆栈式操作,则将您的 goroutine 锁定到操作系统级线程。 (如果你将它与 Go 指针一起使用,你可能还需要告诉编译器不要移动你的 goroutine 堆栈,这是通过特殊的编译时指令完成的。)

编辑:作为kostix notes in a comment,运行时系统将unsafe.Pointer 视为对对象的引用,从而使对象保持活动状态以供GC。它uintptr 视为此类引用。 (也就是说,unsafe.Pointer 具有指针类型,而 uintptr 具有整数类型。)另请参见 documentation for the unsafe package

【讨论】:

  • 为了让这个好答案不那么神奇... — uintptr 可以包含任何指针值,但是 — 与 unsafe.Pointers 相反,GC 不会将 uintptrs 视为对他们指向的内存块。这就是为什么它们只能在某些狭窄的受控情况下使用。
【解决方案2】:

uintptr 只是内存地址的整数表示,与它指向的实际类型无关。有点像 C 中的 void *,或者只是将指针转换为整数。它的目的是在不安全的黑魔法中使用,而不是在日常的 go 代码中使用。

【讨论】:

    【解决方案3】:

    您将 uintptr 和 *uint 混为一谈。 uintptr 在处理指针时使用,它是一种大到足以容纳指针的数据类型。主要用于不安全的内存访问,查看unsafe包。 *uint 是一个指向无符号整数的指针。

    【讨论】:

    • 所以在这个exampleuintptr(session) 似乎将值转换为指针,而 ptr 实际上 没有用作指针。还是 uintptr() 内部获取了 int 的指针?
    • uintptr 只是一个足以容纳指针的整数。它仍然是一个整数。系统调用会将指针解释为指针。
    猜你喜欢
    • 2021-11-09
    • 1970-01-01
    • 2011-04-13
    • 2016-05-03
    • 2012-10-21
    • 1970-01-01
    • 2020-08-08
    • 2012-10-06
    • 1970-01-01
    相关资源
    最近更新 更多