> ## Content Index
> Fetch the complete content index at: https://huizhou92.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Golang 1.23: Changes to //go:linkname and What It Means for Developers
- URL: https://huizhou92.com/golang-1-23-changes-to-go-linkname-and-what-it-means-for-developers/
- Published: 2024-05-28T22:29:13.000Z
- Updated: 2026-09-08T02:32:03.000Z
- Description: Golang 1.23: Changes to //go:linkname and What It Means for Developers. Last week, Go 1.23 entered the freeze period, meaning no new features will be added。
- Author: huizhou92
- Tags: #Migrated-1788833207488, #Import 2026-09-08 02:07

Last week, Go 1.23 entered the freeze period, meaning no new features will be added, and any already added features are unlikely to be removed. This is a great opportunity to preview the upcoming changes.

[Today is the Development Freeze - May 22nd, 2024 11:59 pm (EDT)Skip to first unread message Carlos Amedee unread, May 22, 2024, 10:59:35 AM (4 days ago) May 22 Hi Gophers, This is a…![](https://huizhou92.com/content/images/2026/09/0-zvi_lk0pco6gmtxt.jpg)](https://groups.google.com/g/golang-dev/c/vXE304%5FMnKM?ref=huizhou92.com)

Today, we will discuss the changes to the `//go:linkname` directive in Go 1.23.  
Related issue:

[cmd/link: lock down future uses of linkname · Issue #67401 · golang/goOveruse of //go:linkname to reach into Go standard library internals (especially runtime internals) means that when we…![](https://huizhou92.com/content/images/2026/09/0-4mp9blinnzcricqn.png)](https://github.com/golang/go/issues/67401?ref=huizhou92.com)

**TL;DR** The `//go:linkname` directive is not officially recommended and does not guarantee any forward or backward compatibility. It is wise to avoid using it whenever possible.

With that in mind, let’s dive into the new changes and see how they relate to us.

### What Does the `linkname` Directive Do?

In simple terms, the `linkname` directive is used to pass information to the compiler and linker. Depending on its usage, it can be divided into three categories:

#### 1\. Pull

The “pull” usage is as follows:

```go
import _ "unsafe" // Required to use linkname 
 ​ 
 import _ "fmt" // The pulled package must be explicitly imported (except the runtime package) 
 ​ 
 //go:linkname my_func fmt.Println 
 func my_func(...any) (n int, err error)
```

This directive format is `//go:linkname <local function or package-level variable> <fully defined function or variable in this or another package>`. It tells the compiler and linker that `my_func` should directly use `fmt.Println`, making `my_func` an alias for `fmt.Println`.

This allows ignoring whether functions or variables are exported, pulling even package-private elements into use. However, this method is risky and can lead to panic if there’s a type mismatch.

#### 2\. Push

The “push” usage looks like this:

```go
import _ "unsafe" // Required to use linkname 
 ​ 
 //go:linkname main.fastHandle 
 func fastHandle(input io.Writer) error { 
 ... 
 } 
 ​ 
 // package main 
 func fastHandle(input io.Writer) error 
 ​ 
 // The main package can directly use fastHandle
```

Here, you only need to pass the function or variable name as the first parameter to the directive, specifying the package name where it should be used. This usage signifies that the function or variable will be named `xxx.yyy`.

#### 3\. Handshake

The “handshake” usage combines both methods:

```go
package mypkg 
 ​ 
 import _ "unsafe" // Required to use linkname 
 ​ 
 //go:linkname fastHandle 
 func fastHandle(input io.Writer) error { 
 ... 
 } 
 ​ 
 package main 
 ​ 
 import _ "unsafe" // Required to use linkname 
 ​ 
 //go:linkname fastHandle mypkg.fastHandle 
 func fastHandle(input io.Writer) error
```

The pull side remains unchanged, but the push side doesn’t need to specify the package name. This usage implies a handshake between the two ends, clearly marking which function or variable should be linked.

### Risks of `linkname`

The primary risk is the ability to use package-private functions or variables without the package’s knowledge.  
 For example:

```go
// pkg/mymath/mymath.go 
 package mymath 
 ​ 
 func uintPow(n uint) uint { 
     return n * n 
 } 
 ​ 
 // main.go 
 package main 
 ​ 
 import ( 
     "fmt" 
     _ "linkname/pkg/mymath" 
     _ "unsafe" 
 ) 
 ​ 
 //go:linkname pow linkname/pkg/mymath.uintPow 
 func pow(n uint) uint 
 ​ 
 func main() { 
     fmt.Println(pow(6)) // 36 
 }
```

Normally, `uintPow` shouldn't be accessible outside its package. But `linkname` bypasses this restriction, which can lead to severe type-related memory errors or runtime panics.

### Positive Aspects of `linkname`

Despite its risks, `linkname` exists for valid reasons, such as during the startup of Go programs. For example, in Go’s runtime:

```go
// runtime/proc.go 
 ​ 
 //go:linkname main_main main.main 
 func main_main() 
 ​ 
 // runtime.main 
 func main() { 
     fn := main_main 
     fn() 
 }
```

Here, `linkname` allows the runtime to call the user-defined `main` function.

### Changes to `linkname` in Go 1.23

Given the risks, the Go core team has decided to limit `linkname` usage:

1. New standard library packages will prohibit `linkname`.
2. A new ldflag, `-checklinkname=1`, has been added to enforce restrictions. It defaults to 0 but will be set to 1 in the final release of 1.23.
3. Pull-only `linkname` will be prohibited for the standard library, allowing only the handshake mode.

For instance, the following code will no longer compile in 1.23:

```go
package main 
 import _ "unsafe" 
 //go:linkname corostart runtime.corostart 
 func corostart() 
 ​ 
 func main() { 
     corostart() 
 }
```

### Future of `linkname`

The long-term goal is only to allow handshake mode. As developers, we should:

1. Use `-checklinkname=1` to audit and remove unnecessary `linkname` usage.
2. Propose to make private APIs public if necessary.
3. As a last resort, disable the restriction with `-ldflags=-checklinkname=0`.

### Conclusion

In summary, avoid using `//go:linkname` to prevent unforeseen issues.

### More Reading

1. [The long-overdue problem coming for some people in Go 1.23](https://utcc.utoronto.ca/~cks/space/blog/programming/Go123LinknameComingProblem?ref=huizhou92.com)

[文章索引](/article-index/)