# Header Translation

### Header Translation

`@cImport` does two jobs.

It asks the C compiler front end to read a header, and it asks Zig to translate the visible C declarations into Zig declarations.

For this C header:

```c
#ifndef MATHLIB_H
#define MATHLIB_H

int add(int a, int b);
double mean(double a, double b);

#endif
```

Zig can import it:

```zig
const c = @cImport({
    @cInclude("mathlib.h");
});
```

The declarations are then used through `c`:

```zig
const std = @import("std");

const c = @cImport({
    @cInclude("mathlib.h");
});

pub fn main() void {
    const x = c.add(2, 5);
    const y = c.mean(10.0, 20.0);

    std.debug.print("{d} {d}\n", .{ x, y });
}
```

Build it with the header path and C source:

```sh
zig run main.zig mathlib.c -I.
```

A function prototype in C becomes an external function declaration in Zig.

```c
int add(int a, int b);
```

is translated as a function that can be called as:

```zig
c.add(2, 5)
```

A C struct becomes a Zig extern struct.

```c
struct Point {
    int x;
    int y;
};
```

It can be used from Zig:

```zig
const c = @cImport({
    @cInclude("point.h");
});

pub fn main() void {
    var p = c.struct_Point{
        .x = 10,
        .y = 20,
    };

    _ = p;
}
```

The exact translated name depends on the C declaration. Named C structs commonly appear with names such as `struct_Point`.

A C typedef gives a more pleasant name.

```c
typedef struct {
    int x;
    int y;
} Point;
```

Then Zig code can use:

```zig
var p = c.Point{
    .x = 10,
    .y = 20,
};
```

This is usually the better C header style for Zig users.

Macros are more limited.

Simple numeric macros translate well:

```c
#define MAX_COUNT 1024
```

can be used as:

```zig
const n = c.MAX_COUNT;
```

Function-like macros may or may not translate. Zig can translate some simple macros, but C macros are token substitution, not typed declarations. Complex macros should be treated as C code, not as a clean Zig interface.

For example, this is clear in C:

```c
#define SQUARE(x) ((x) * (x))
```

But in Zig it is often better to write a Zig function:

```zig
fn square(x: i32) i32 {
    return x * x;
}
```

C enums are translated into Zig values whose exact shape follows the C ABI. Do not assume they behave like ordinary Zig enum types unless you check the translated declaration.

C pointers also keep their C nature. A declaration such as:

```c
const char *name(void);
```

is best treated in Zig as a pointer to zero-terminated bytes:

```zig
const s = c.name();
```

Before using it as a Zig slice, measure its length or convert it carefully.

The rule is simple: translated headers preserve the C interface. They do not turn C into idiomatic Zig.

For a large library, this is an advantage. The header remains the source of truth. Zig tracks the ABI. The Zig program decides where to add a safer, clearer wrapper.

