【发布时间】:2021-09-22 10:48:46
【问题描述】:
根据CGO(https://pkg.go.dev/cmd/cgo)的文档,在实现中有一个已知的bug:
注意:当前的实现有一个错误。虽然允许 Go 代码将 nil 或 C 指针(但不是 Go 指针)写入 C 内存,但如果 C 内存的内容看起来是 Go 指针,当前实现有时可能会导致运行时错误。因此,如果 Go 代码要在其中存储指针值,请避免将未初始化的 C 内存传递给 Go 代码。在将 C 中的内存传递给 Go 之前将其清零。
我在 GitHub 的问题跟踪器中查找了此内容,但在那里找不到。有人可以详细说明为什么会发生这种情况吗?运行时如何在未初始化的 C 内存中找到 Go 指针?
例如。假设我将一个未初始化的 char 数组从 C 传递给 Go 函数,运行时如何解释此内存中的 Go 指针?
此外,“如果 Go 代码要在其中存储指针值”部分让我感到困惑。为什么以后使用此内存很重要?
【问题讨论】:
-
"...运行时如何解释此内存中的 Go 指针",除非您使用它来存储指针,否则它不会。它回答了你引用的下一句话:“如果 Go 代码要在其中存储指针值,请避免将未初始化的 C 内存传递给 Go 代码”。
-
@JimB,我不是母语人士,但对我来说,手册的引用部分似乎没有提到 C 内存块中的 chasing 指针,它更确切地说是存储指针 into ——也就是说,直接存储。所以,一方面,我支持OP的混乱。你怎么看?
-
@kostix:我认为这一切都归结为“如果 Go 代码要在其中存储指针值,请避免将未初始化的 C 内存传递给 Go 代码”,即一个清晰而简单的指示。剩下的只是尝试提供一些背景知识,而不必完全解释垃圾收集器如何扫描指针。
-
令我困惑的是,这被称为错误。这不是更多的故障安全,它有一个副作用突然出现在毫无戒心的程序员身上吗?
-
引用给出了关于如何避免问题的简单说明,但该说明似乎与引用的第一句话脱节。开头似乎描述了一个更广泛的问题。我想更详细地描述错误和触发它的条件。这不需要对指针扫描的完整解释。令我感到奇怪的是,一个新的条件,减少了错误的范围,首先出现在“因此”之后。