In Go 1.23, the standard library introduced the structs package, providing the structs.HostLayout marker type. Adding _ structs.HostLayout to a struct definition explicitly instructs the compiler to guarantee that the memory layout (including field ordering, alignment, and padding) matches the target platform's C ABI.
Since goffi targets Go 1.25+ as specified in go.mod, we can leverage this standard compiler guarantee to replace the implicit assumption that Go's default struct layout will always match C ABI.
The following low-level structures in goffi are laid out in memory according to expectations in assembly files (offsets) and standard C library interfaces, and would benefit from structs.HostLayout:
-
callbackArgs (defined in ffi/callback.go and ffi/callback_arm64.go)
This structure is populated directly by assembly trampolines and must match the register/stack layout.
-
G and ThreadStart (defined in internal/fakecgo/libcgo.go)
These structures are shared directly with POSIX and Windows threads.
-
dlopenArgs, dlsymArgs, and dlerrorArgs (defined in internal/dl/dl_unix.go)
These structures are passed to Go's runtime dynamic loader wrappers (dlopen_wrapper, etc.) and require strict memory layout alignment.
Proposed Changes:
For each of the structures listed above:
- Import the standard
"structs" package.
- Add
_ structs.HostLayout as the first field.
This change does not impact runtime behavior but makes the FFI layer highly resilient against any future Go compiler changes regarding default struct optimization/reordering.
In Go 1.23, the standard library introduced the
structspackage, providing thestructs.HostLayoutmarker type. Adding_ structs.HostLayoutto a struct definition explicitly instructs the compiler to guarantee that the memory layout (including field ordering, alignment, and padding) matches the target platform's C ABI.Since
goffitargets Go 1.25+ as specified ingo.mod, we can leverage this standard compiler guarantee to replace the implicit assumption that Go's default struct layout will always match C ABI.The following low-level structures in
goffiare laid out in memory according to expectations in assembly files (offsets) and standard C library interfaces, and would benefit fromstructs.HostLayout:callbackArgs(defined inffi/callback.goandffi/callback_arm64.go)This structure is populated directly by assembly trampolines and must match the register/stack layout.
GandThreadStart(defined ininternal/fakecgo/libcgo.go)These structures are shared directly with POSIX and Windows threads.
dlopenArgs,dlsymArgs, anddlerrorArgs(defined ininternal/dl/dl_unix.go)These structures are passed to Go's runtime dynamic loader wrappers (
dlopen_wrapper, etc.) and require strict memory layout alignment.Proposed Changes:
For each of the structures listed above:
"structs"package._ structs.HostLayoutas the first field.This change does not impact runtime behavior but makes the FFI layer highly resilient against any future Go compiler changes regarding default struct optimization/reordering.