Go’s Wall of Shame and the Forbidden 'linkname' directive
By nevillecain on May 10, 2025
While reading through some of the Go source code, I noticed quite a few comments with this little line:
// Notable members of the hall of shame include:
You can grep it yourself:
grep "members of the hall of shame" -rni *
It turns out that some Go maintainers are keeping an informal callout list: a public list of packages that are, in their view, misusing certain internal features. Most of it relates to the infamous //go:linkname
directive.
Before diving into a concrete example, let’s quickly explain what a directive is in Go.
🔧 What’s a Directive in Go?
It’s a comment that controls the behavior of the Go toolchain — the compiler, linker, or generators. You’ve probably used one without even thinking much about it, for example:
//go:generate go run gen.go
This works with the go generate
command, which looks for //go:generate
lines and runs them as shell commands.
Another (less known) directive is //go:linkname
. It’s the one responsible for this mysterious "hall of shame" comment trail.
🔗 What is //go:linkname
?
The linkname
directive lets you link a local Go function to a symbol (even unexported) in another package, including standard library ones.
Let’s look at a real example. In the time
package, there’s a private function:
//go:linkname nextStdChunk
func nextStdChunk(layout string) (prefix string, std int, suffix string) {
...
}
This function is not exported, meaning you can’t just write time.nextStdChunk
in your own code.
Still, with linkname
, you can basically tell the linker:
“Hey, I know what I’m doing. Trust me.”
Here’s how you can actually call that internal function:
package main
import (
"fmt"
_ "unsafe"
)
//go:linkname nextStdChunk time.nextStdChunk
func nextStdChunk(layout string) (prefix string, std int, suffix string)
func main() {
prefix, std, suffix := nextStdChunk("2006-01-02 15:04:05")
fmt.Println("Prefix:", prefix)
fmt.Println("Std:", std)
fmt.Println("Suffix:", suffix)
}
And when you run it:
go run main.go
You’ll get output like:
Prefix:
Std: 275
Suffix: -01-02 15:04:05
We don’t really care about the output but the point is: you just called a private function from the standard library.
🧱 Why This Is Controversial
Go’s core team uses //go:linkname
internally for legit reasons, e.g. to reuse internal helpers across packages without exposing them publicly. But they really don’t want external users doing the same thing.
Still, people do it anyway.
Interestingly, from my testing, trying to use linkname
to access private functions in your own packages (non-stdlib) doesn’t work as easily, it looks like Go adds protection layers there.
About the Author
Software developer specialized in backend systems.