# C+ for LLMs

C+ is deliberately shaped so a model can produce useful systems code with a small correction loop. The language avoids features that need hidden global knowledge: no overload sets, no implicit conversions, no closures with capture rules, no exceptions, no macros, no `null`, and no reference types. Most meaning is visible in the local function signature: ownership markers are on parameters, `unsafe` is written at the operation, imports name their source, and generic arguments use `::[T]` instead of the grammar-ambiguous `<T>`.

## Small surface, strong diagnostics

The compiler is meant to be part of writing the code, not just the gate at the end. A model can emit a first draft, run [`cpc check` or `cpc build`](/docs/tooling), then use the [diagnostic code](/docs/error-codes) and span to repair the program. The codes are specific: `E0302` is a type mismatch, `E0335` is use after move, `E0340` is a non-exhaustive match, `E0801` is an operation that needs an `unsafe` block. `cpc --diagnostics=json` exposes the same information in a machine-readable shape.

Formatting is part of the contract too. `cpc fmt` gives one canonical layout, so repeated edits do not accumulate style noise, and `cpc fmt --check` lets CI reject drift.

## Querying code as a graph, not as text

Navigating C+ by `grep` is lossy: text search cannot tell the `Point` struct from a local named `point`, follow `prefix::Item` to the module that defines it, or answer "who calls this". `cpc` exposes the resolved, typed code graph the compiler already computes and makes it queryable by symbol and type:

```bash
cpc query def    math::area              # resolved definition site(s)
cpc query callers process_frame          # who calls it
cpc query type-at src/main.cplus:42:10   # type under a cursor
cpc query context parse                  # one-shot edit pack
```

Every query returns JSON with the same `file:line:col` shape diagnostics use, so an agent acts on a result without parsing prose. Because the lookups are resolved rather than name-based, `math::area` and a local `area` are distinguished, and a method call binds to the concrete `Type::method` it dispatches to. Results carry an explicit `unresolved` / `scope` field, so an agent knows exactly where coverage ends and a `grep` fallback is still needed.

For the agent loop, **`cpc mcp`** is a resident MCP server: it builds the graph once, keeps it warm, and exposes the queries as tools over stdio (newline-delimited JSON-RPC). Point an MCP client at `cpc mcp` to give an agent resolved, typed navigation (`find_definition`, `find_references`, `find_callers`, `code_context`, `type_at`) in place of `grep`. The same index backs `cpc lsp`, so editor and agent share one resolved view of the code.

## Hand-emitted LLVM IR

`cpc` does not build IR through LLVM's C++ API; it emits textual LLVM IR and hands the `.ll` to the normal toolchain. That is unusually friendly to agents, because the IR is an inspectable, patchable debugging surface:

```bash
cpc --emit-ll FILE       # exact pre-optimisation IR
cpc --emit-ll-opt FILE   # what LLVM kept after optimisation
cpc --emit-asm FILE      # native output, when ABI or perf details matter
```

IR diffs are plain text, so a codegen regression can be compared against C/Clang output and fixed without knowing LLVM's builder API.

## Contracts an agent can check

C+ prefers explicit contracts the compiler can reject. `#[repr(C)]` says a type crosses an ABI boundary, `restrict` says raw-pointer parameters do not alias, and `#[no_alloc]` / `#[no_block]` / `#[max_stack(N)]` / [`#[realtime]`](/docs/realtime) say a hot path must avoid allocation, blocking, an oversized frame, and recursion cycles. A `[profile.realtime]` manifest table applies them project-wide so `cpc check` becomes a CI gate. These turn a vague requirement ("make this audio callback real-time safe") into concrete diagnostics a model can act on.

## The practical loop

```bash
cpc fmt src/main.cplus
cpc build
cpc build --diagnostics=json
```

Use `cpc build` for project code and single-file `cpc check FILE` for import-free snippets. If an answer depends on current compiler behavior, the compiler wins over any prose. For a dense, imperative generation guide, see the [Writing correct C+](/guides/writing-correct-cplus) tutorial.
