logoalt Hacker News

Eliminating Go bounds checks with unsafe

46 pointsby abnercoimbre07/14/202619 commentsview on HN

Comments

naruhodoyesterday at 9:58 AM

I like reading articles like this, but as per usual, I also find these articles frustrating to read because they don't specify calling conventions[0] (which are many and varied) - particularly the allocation of arguments to registers and the stack frame.

Articles about GoLang assembly language[1] are particularly vexing because the instruction parameters are bass-ackwards - source, destination - like AT&T syntax, but register references are missing their % sigil and so appear to be MASM-style[2].

Authors blogging from deep inside some technical tent should take pity on readers who are not so deeply in the tent and offer a brief primer on assumed knowledge.

Any mistakes in the above should be viewed as confirmation of my confusion.

[0] https://en.wikipedia.org/wiki/X86_calling_conventions

[1] https://go.dev/doc/asm#x86

[2]https://en.wikipedia.org/wiki/X86_assembly_language

show 1 reply
pjmlpyesterday at 11:27 AM

> As I already complained I wish Go had the nobounds compiler hint but it doesn't, so the only viable option we are left with is using unsafe pointer arithmetic.

Because what the IT infrastructure needs is more CVEs.

archargelodyesterday at 9:33 AM

Is there any way in Go to selectively turn off bounds checking for a block, function or module? E.g. in Nim I can just do:

    proc littleEndian(b: openarray[byte]): uint32 =
      {.push boundChecks: off.}
      return uint32(b[0]) or (uint32(b[1]) shl 8) or (uint32(b[2]) shl 16) or (uint32(b[3]) shl 24)
      {.pop.}
And GCC is smart enough to reduce it to a single operation:

    000000000000bf80 <littleEndian_u0__session95202695079520951784538200>:
        bf80:       8b 07                   mov    (%rdi),%eax
        bf82:       c3                      ret
show 1 reply
ncrucesyesterday at 11:52 AM

The article should note this: it's important that you don't go adding other/all little endian platforms to that go:build line.

The article is correct, but this code is only valid for platforms that allow unaligned access.

You can get the full list of platforms that Go considers safe for this from unalignedOK here: https://go.dev/src/cmd/compile/internal/ssa/config.go

You want the intersection of unalignedOK with little endian.

espetroyesterday at 4:28 PM

Nice article Andrii. I see from previous articles <https://blog.andr2i.com/posts/2026-06-22-optimization-catalo...> that you can identify and validate bottlenecks which you can optimize.

For more general Go practitioners like me, is there any harness/tooling I can bring into my projects to identify these bottlenecks (aside from profiling if any). More specifically, tooling that identifies workflows that actually have greater changes to be fine with 'unsafe'.

lou1306yesterday at 9:27 AM

Question from someone trying to get better at Go: _before_ going all in with unsafe pointer operations, would it make sense to write a function harness & profile it with/without the -B flag to determine the actual impact of bounds check?

show 3 replies
5701652400yesterday at 9:06 AM

does profile guided optimisation reduce these checks?

show 1 reply
ianeffyesterday at 10:33 AM

This was great, thank you!