Search docsSearch this language
Getting started
Release candidatev0.20260809.0-rc.5

These docs describe the current coordinated release candidate.

Getting started

Overview

What C2Go produces, where it runs, and when it is a good fit.

C2Go is a Clang mode that compiles C source into artifacts the Go toolchain can build as a Go package. The resulting code runs under the Go runtime: it uses goroutine stacks and scheduling, can allocate objects visible to the Go garbage collector, and can call across the C/Go boundary.

This is ahead-of-time compilation. C2Go does not embed a C compiler in your application and it does not compile C at startup.

What the toolchain produces

For one or more C translation units, c2go-clang produces:

  • Plan 9 assembly (.s) for the Go assembler;
  • a JSON manifest describing exported symbols, types, target information, callbacks, and linker inputs.

c2go-bind consumes the assembly and manifest and writes generated .go and .s files into a normal Go package. go build or go test completes the build.

The generated package does not use import "C". c2go-libc integrates a PureGo native-call bridge, so consumers can build with CGO_ENABLED=0 and no host C compiler; only the generation step requires the C2Go toolchain.

C source
   │
   ▼
c2go-clang + c2go-lto
   │  Plan 9 assembly + JSON manifest
   ▼
c2go-bind
   │  generated .go + .s package
   ▼
Go toolchain + c2go-libc

What is different from ordinary C

C2Go adds an explicit distinction between two memory worlds. In the current implementation, the translation-unit default is unmanaged. Normally, use a bare #pragma c2go managed push region to enable every managed default, or apply record/pointer attributes for local annotations:

  • managed values participate in the Go runtime’s memory model and carry precise GC metadata;
  • unmanaged values represent native C memory and external C ABI boundaries.

That distinction lets the compiler preserve precise GC information. It also means some C operations that are normally unchecked become warnings or errors when they could hide pointers from the collector.

The public extensions in <c2go.h> include:

Feature Purpose
gc_malloc and c2go_typeinfo Allocate typed objects on the Go heap
c2go_extern Export a defined C function to Go
c2go_linkname Bind a C declaration to a Go symbol
unmanaged Explicitly mark a native representation or boundary
c2go_callback / c2go_callout Move callable function pointers across the boundary
c2go_returntype Describe a Go multi-value result with a C struct

For the complete spelling, category, and constraints of each extension, use the C2Go extensions reference.

Release baseline

The current coordinated release is built around:

  • C only; C++ is not supported;
  • 64-bit amd64 and arm64 code generation;
  • Go 1.25.x and Go 1.26.x for the current SDK release;
  • separate generated output for each OS and architecture; and
  • pre-1.0 APIs and ABI details that may still change.

The release page lists the host SDK archives that are actually built and tested. Before migrating an existing library, review Platforms and current limitations for the canonical language, ABI, callback, and packaging boundaries.

When to use C2Go

C2Go is useful when you want to port or reuse C implementation code while presenting a normal Go package to its consumers. It is especially relevant when the code benefits from Go-managed allocation or needs tighter runtime integration than a conventional process boundary.

It is not yet a drop-in replacement for every cgo project. Use the linked limitations page as the adoption checklist instead of assuming that every construct accepted by upstream Clang is part of the C2Go release contract.

Next step

Install the matching SDK and Go runtime module, then compile one exported C function in Hello World.