33. cgo and syscalls, briefly
33.1 cgo: calling C from Go
/*
#include <stdlib.h>
*/
import "C"
func randomC() int {
return int(C.rand())
}
cgo lets Go call into existing C libraries, at real costs: it disables
cross-compilation convenience (you now need a C toolchain for the
target), it's slower per-call than a pure-Go function call (a few dozen
nanoseconds of overhead per cgo call, from stack-switching), and it
complicates static linking. Use it only when a mature C library
genuinely has no Go equivalent worth the switch (common with certain
crypto, image codecs, or hardware SDKs).
33.2 Direct syscalls without cgo
The syscall and golang.org/x/sys/unix packages let you call the OS
directly in pure Go, preserving cross-compilation and static linking —
this is how Go implements os.Open, net.Listen, etc. under the hood,
and it's the preferred route over cgo whenever the functionality is
just "talk to the kernel," not "use this specific C library's algorithm."
33.3 Real-world example
Docker and Kubernetes are written in pure Go specifically so they remain
statically-linked, cross-compilable, dependency-free binaries — both
avoid cgo in their core paths for exactly this reason, reaching for
golang.org/x/sys/unix when they need raw namespace/cgroup syscalls.
Applied in the series: the TCP/IP guide's tcpinfo reads TCP_INFO with SyscallConn().Control; the Linux guide's minicontainer uses SysProcAttr clone flags and CgroupFD.