# cgo (/docs/cgo)

<Callout title="New">
cgo support is new. Cross builds of cgo packages are not supported yet.
</Callout>

Packages that `import "C"` build unchanged. marmot runs `cmd/cgo` and compiles the generated
code and the package's `.c`, `.s` and `.S` files with clang. `#cgo CFLAGS`, `LDFLAGS` and
`pkg-config` lines work, and are checked against the same allowlists as the go command.

```go
package main

/*
#include <stdlib.h>
#include <string.h>

static int twice(int x) { return 2 * x; }
*/
import "C"

import (
	"fmt"
	"unsafe"
)

func main() {
	s := C.CString("marmot")
	defer C.free(unsafe.Pointer(s))
	fmt.Println(C.strlen(s), C.twice(21))
}
```

## Cheaper calls [#cheaper-calls]

A call to a C function is a direct native call with the C ABI, on the goroutine's own stack.
There is no argument frame and no switch to another stack. The runtime is told when a goroutine
enters and leaves C so the scheduler can keep other goroutines running; for functions marked
with both `#cgo noescape` and `#cgo nocallback`, and for libc leaf functions, even that is
reduced to a mark.

<table>
  <thead><tr><th>cost of one call to an empty C function</th><th>marmot</th><th>go (cgo)</th></tr></thead>
  <tbody><tr><td>linux/amd64, -release</td><td>2.3 ns</td><td>33 to 57 ns</td></tr></tbody>
</table>

In release builds the C code is compiled to LLVM bitcode and optimized together with the Go
code, so small C functions can be inlined into Go.

## What works [#what-works]

- C functions, variables, constants, structs, unions, arrays, enums and function pointers.
- `C.CString`, `C.GoString`, `C.GoStringN`, `C.GoBytes`, `C.CBytes`, `C.malloc` and `C.free`.
- The `errno` second result.
- `//export`: C calling Go, including nested calls, blocking callbacks and threads created in C.
- `marmot test` of cgo packages.
- Blocking C calls do not stop other goroutines.

## Not yet [#not-yet]

- Cross builds (`-target`) of cgo packages.

A fault inside a C call stops the program with a fatal error.